Coding is more of an art than science.A good code should attract sincerity, a pattern and design should be evident. 

Write Code is a modular Fashion.

Start with a Problem and break the problem into multiple small bite-size solutions.

modular programming, Efficient programming.
Modular-programming

Make the function names and variables more readable. A code-reader/reviewer glances at the code and understands what the code is doing instead of tangling into the nitty-gritty of computing logic.


Code Layering

Code-snnipet
Util file example

• Hide all smaller and reusable functions behind in a util file, the main function should not go too deep. The depth of solving a problem should be left at 1 level below.

For Example Let’s say A Simple Application consists of 3 functionalities

Parse cmd line args

Init function

Pkt handling Logic

Exit

Then all these functions should be used and error/-ve logic should be handled here.
E.g

main(int argc, char*argv[])
{
	ret =parse_cmd_line(argc, argv);
	If (-1 == ret)
	{
		Log_err(“Error in parse_cmd_line”,);
		return -1;
	}
	ret = init();
	if(-1 == ret)
	{
		Log_err(“Error in initialization ”,);
			return -1;
}
ret =pkt_handler(global_var, &error_code);
if(-1 == ret)
{
	Log_err(“Error in  pkt_handler%d ”,error_code);
	Return -1;
}
}

All the intricacies of parse_cmd_line(), init(), pkt_hdlr() are hidden.

For the sake of Simplicity ,If you take a peek inside  init() function, then

It should be like this

/*Init function
@in : none
@out : 0 fail, 1 success
*/
Int init()
{
Hw_ret = hw_init();
if(hw_ret)// 1 is a success and 0 is fail
	sw_ret = sw_init();
	if(sw_ret)
		Init_mother_struct
		init_socket();
		init_mempool();
	Init_ret = sw_ret && hw_ret;
	return init_ret;
}

 DPDK is all about performance, it provides you tools at disposal to get your peak performance.

To reveal the secret I have learned after putting 300hrs  coding in dpdk.

DPDK APPLICATION LOGICAL BREAK-DOWN

Any dpdk application does these 6 steps.

dpdk-programing-steps
dpdk programing_steps-1

Now you have the pandora’s box open, You can google them and learn more.But you have landed here after doing so 🙂 . So I am going to explain.

Well each of these 6 steps requires a post of their own, 

But I am going to do a brief about them.

EAL-INIT

1.EAL init (arg, argv) : This function is analogous to parse_cmd_line() + init()

Intent of this function is 

»Scan &Detect dpdk compatible pci devices.

»Initialize Huge pages 

»Understand the memory map of the detected pci devices 

»Identify the suitable Poll Mode driver for each of the detected device.

»In Doing the above process they also initalise many internal data-srtuctures and linked-lists.

»Also they do many more operations based on cmd line args provided details can be found here.

EAL-INIT -WHAT ALL HAPPENS?

PORT/DEVICE CONFIGURE

2.Port/Device Configure: Okay EAL-init is successful (if eal_init is unsuccessful, return value is -1 then your program will exit.)what should we do next??

Our Logical step would be to find how many ethernet-ports have been detected…If no Ethernet-ports(aka nic ) are detected then we can’t do anything..!! Can we?, No port detected; So can’t do Rx or Tx, We should bailout(or exit). However !!! if we did found at least one port we can do something… maybe just sniffing the packet or listen in promiscuous mode.

Remember the number of devices detected in step 1.

»No_of_ports = rte_eth_dev_count_avail(), This will give you the number of dpdk compatible ethernet ports detected.

Configure Tx & Rx Queues for each port. Each ethernet device will have on queue pair for rx/tx for full duplex communication. Via this queue only dpdk will receive pkts into the dpdk application and dpdk app will write pkt in this queue to xmit.

MEMPOOL/HASH CREATE

 3.Mempool/Hash Create: Any packet processing application will need memory to store receiving traffic . And have them freed once done with the packet.

Same goes for Tx pkt as well, When you create/form a pkt you need memory and the same needs to be freed post .

For starters rte_zmalloc() & rte_free() are 2 function which you should use, before you understand the logic of memory pools and mem zones. And dont get under complex when some-one throws you a jargaon of “Zero-Copy Buffer & Lockless queues, Probably the person asking you, doesnot know the simple answer”.

One More Secret.

While transmitting you (application)need to alloc a memory , which will be transmitted on the Tx Queue and will be freed by dpdk itself, 

While pkt Rx, memory is allocated by dpdk and pointer is stored in the Rx queue.This pkt when processed needs to be freed by the you(application). Once you are done either pkt fwd, modifying, dropping etc you need to free, the rx_buffer

DEVICE START

4.Device Start: As in Socket Programming before calling send or recv functions you need to do a bunch of things.

Same way You need to configure the device, E.g enable promiscuous mode.

»Set mtu size

»Set semi-duplex/full.

»Check Link Status.

 These are few  examples. But many more options are there.  Till this point you are configuring the ethernet-devices. Once you do rte_device_start(port_id). All your configurations are punched in and ethernet-port is engined on to do Rx and tx.

Post this if you call rte_eth_rx_burst(port_id, p_pkt[ ] , nb_pkt)

You will receive array of pkt pointer and the number of pkts received is present in nb_pkt 

Usually this value is in the range of 0 to 32.

rte_eth_tx_burst(port_id, **pkt_buf_arr, nb_tx)
If you would like to add something please comment.

0 0 votes
Article Rating
Previous articleSmartNIC’s and Beyond
Next articleSMART HOME IDEAS IN 2020
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments