[dpdk-dev] proposal: raw packet send and receive API for PMD driver

Guojiachun guojiachun at huawei.com
Thu May 14 02:26:55 CEST 2015


Hello,

This is our proposal to introduce new PMD APIs, it would be much better to integrate DPDK into various applications.

There is a gap in hardware offload when you porting DPDK to new platform which support some offload features, like packet accelerator, buffer management etc.
If we can make some supplement to it. It will be easy for porting DPDK to new NIC/platform.


1.      Packet buffer management

The PMD driver use DPDK software mempool API to get/put packet buffer in currently. But in other cases, the hardware maybe support buffer management unit. We can use hardware buffer-unit replaces DPDK software mempool to gain efficiencies. So we need to register get/put hook APIs to these eth_dev. Defined as following:

/* <obj_table> include <data: virtual addr> and <phys_addr> */

typedef int (*rbuf_bulk_get_hook)(void* mempool, void **obj_table, unsigned n);

typedef int (*rbuf_bulk_free_hook)(void* memaddr);



typedef int (*eth_dev_init_t)(struct eth_driver  *eth_drv,  struct rte_eth_dev *eth_dev,
                                rbuf_bulk_get_hook *rbuf_get,  rbuf_bulk_free_hook *rbuf_free);

         If there are no hardware buffer-unit, we can register the currently rte_mempool APIs in eth_dev_init(). Each driver use these API hook but not rte_mempool_get_bulk()/rte_mempool_put().


2.      Recv/send API and raw_buf

The hardware offload feature differences exist between the NICs. Currently defined in rte_mbuf for rx/tx offload can't applying all NIC. And sometimes modifying rte_mbuf also need to modify all PMD driver. But we can define a union rte_rbuf to resolve it.



struct rte_rbuf {

         void *buf_addr;           /**< Virtual address of segment buffer. */

         phys_addr_t buf_physaddr; /**< Physical address of segment buffer. */

         uint16_t buf_len;         /**< Length of segment buffer. */

      uint16_t data_off;

         uint8_t nb_segs;          /**< Number of segments. */



union{

        struct{

             uint32_t rx_offload_data[8];

             uint32_t tx_offload_data[8];

} offload_data;



struct{ /* intel nic offload define*/

          uint32_t rss;

    uint64_t tx_offload;

      ...

    }intel_offload;



     /* other NIC offload define */

    ...

} /* offload define */

}





3.      RTE_PKTMBUF_HEADROOM

Each PMD driver need to fill rte_mbuf->data_off according to the macro: RTE_PKTMBUF_HEADROOM. But in some cases, different application need different RTE_PKTMBUF_HEADROOM. Once changing the value of RTE_PKTMBUF_HEADROOM, it should to re-compile all drivers. That means different application need different driver lib, but not the same one.

So we can pass a argument dynamically in eth_dev_init() to replace the MACRO: RTE_PKTMBUF_HEADROOM.




Therefore, we can add these APIs as following:


struct rte_rbuf {

         void *buf_addr;           /**< Virtual address of segment buffer. */

         phys_addr_t buf_physaddr; /**< Physical address of segment buffer. */

         uint16_t buf_len;         /**< Length of segment buffer. */

      uint16_t data_off;

         uint8_t nb_segs;          /**< Number of segments. */



union{

        struct{

             uint32_t rx_offload_data[8];

             uint32_t tx_offload_data[8];

} offload_data;



struct{ /* intel nic offload define*/

          uint32_t rss;

    uint64_t tx_offload;

      ...

    }intel_offload;



     /* other NIC offload define */

    ...

} /* offload define */

}

uint16_t rte_eth_tx_raw_burst(uint8_t port_id, uint16_t queue_id, struct rte_rbuf **tx_pkts, uint16_t nb_pkts);
uint16_t rte_eth_rx_raw_burst(uint8_t port_id, uint16_t queue_id, struct rte_rbuf **rx_pkts, uint16_t nb_pkts);

/* <obj_table> include <data: virtual addr> and <phys_addr> */
typedef int (*rbuf_bulk_get_hook)(void* mempool, void **obj_table, unsigned n);
typedef int (*rbuf_bulk_free_hook)(void* memaddr);

/* use 'headroom_offset' to replace compile MARCO(CONFIG_RTE_PKTMBUF_HEADROOM) */
typedef int (*eth_dev_init_t)(struct eth_driver  *eth_drv,  struct rte_eth_dev *eth_dev,
                                rbuf_bulk_get_hook *rbuf_get,  rbuf_bulk_free_hook *rbuf_free, uint16_t headroom_offset);


These are my ideas, I hope you can help me to improve on them.
Thank you!

Jiachun


More information about the dev mailing list