Skip to content

Commit

Permalink
i40e: use 16B HW descriptors instead of 32B
Browse files Browse the repository at this point in the history
The i40e NIC supports two flavors of HW descriptors, 16 and 32
byte. The latter has, obviously, room for more offloading
information. However, the only fields of the 32B HW descriptor that is
being used by the driver, is also available in the 16B descriptor.

In other words; Reading and writing 32 bytes instead of 16 byte is a
waste of bus bandwidth.

This commit starts using 16 byte descriptors instead of 32 byte
descriptors.

For AF_XDP the rx_drop benchmark was improved by 2%.

Signed-off-by: Björn Töpel <bjorn.topel@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
  • Loading branch information
Björn Töpel authored and Tony Nguyen committed Sep 14, 2020
1 parent f78bd13 commit f0064bf
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 17 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/i40e/i40e.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
#define I40E_OEM_RELEASE_MASK 0x0000ffff

#define I40E_RX_DESC(R, i) \
(&(((union i40e_32byte_rx_desc *)((R)->desc))[i]))
(&(((union i40e_rx_desc *)((R)->desc))[i]))
#define I40E_TX_DESC(R, i) \
(&(((struct i40e_tx_desc *)((R)->desc))[i]))
#define I40E_TX_CTXTDESC(R, i) \
Expand Down
10 changes: 4 additions & 6 deletions drivers/net/ethernet/intel/i40e/i40e_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -604,10 +604,9 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
} else {
rxd = I40E_RX_DESC(ring, i);
dev_info(&pf->pdev->dev,
" d[%03x] = 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n",
" d[%03x] = 0x%016llx 0x%016llx\n",
i, rxd->read.pkt_addr,
rxd->read.hdr_addr,
rxd->read.rsvd1, rxd->read.rsvd2);
rxd->read.hdr_addr);
}
}
} else if (cnt == 3) {
Expand All @@ -625,10 +624,9 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
} else {
rxd = I40E_RX_DESC(ring, desc_n);
dev_info(&pf->pdev->dev,
"vsi = %02i rx ring = %02i d[%03x] = 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n",
"vsi = %02i rx ring = %02i d[%03x] = 0x%016llx 0x%016llx\n",
vsi_seid, ring_id, desc_n,
rxd->read.pkt_addr, rxd->read.hdr_addr,
rxd->read.rsvd1, rxd->read.rsvd2);
rxd->read.pkt_addr, rxd->read.hdr_addr);
}
} else {
dev_info(&pf->pdev->dev, "dump desc rx/tx/xdp <vsi_seid> <ring_id> [<desc_n>]\n");
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/intel/i40e/i40e_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3321,8 +3321,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
rx_ctx.base = (ring->dma / 128);
rx_ctx.qlen = ring->count;

/* use 32 byte descriptors */
rx_ctx.dsize = 1;
/* use 16 byte descriptors */
rx_ctx.dsize = 0;

/* descriptor type is always zero
* rx_ctx.dtype = 0;
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/ethernet/intel/i40e/i40e_trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ DECLARE_EVENT_CLASS(
i40e_rx_template,

TP_PROTO(struct i40e_ring *ring,
union i40e_32byte_rx_desc *desc,
union i40e_16byte_rx_desc *desc,
struct sk_buff *skb),

TP_ARGS(ring, desc, skb),
Expand Down Expand Up @@ -140,15 +140,15 @@ DECLARE_EVENT_CLASS(
DEFINE_EVENT(
i40e_rx_template, i40e_clean_rx_irq,
TP_PROTO(struct i40e_ring *ring,
union i40e_32byte_rx_desc *desc,
union i40e_16byte_rx_desc *desc,
struct sk_buff *skb),

TP_ARGS(ring, desc, skb));

DEFINE_EVENT(
i40e_rx_template, i40e_clean_rx_irq_rx,
TP_PROTO(struct i40e_ring *ring,
union i40e_32byte_rx_desc *desc,
union i40e_16byte_rx_desc *desc,
struct sk_buff *skb),

TP_ARGS(ring, desc, skb));
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/ethernet/intel/i40e/i40e_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,11 +533,11 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring, u64 qword0_raw,
{
struct i40e_pf *pf = rx_ring->vsi->back;
struct pci_dev *pdev = pf->pdev;
struct i40e_32b_rx_wb_qw0 *qw0;
struct i40e_16b_rx_wb_qw0 *qw0;
u32 fcnt_prog, fcnt_avail;
u32 error;

qw0 = (struct i40e_32b_rx_wb_qw0 *)&qword0_raw;
qw0 = (struct i40e_16b_rx_wb_qw0 *)&qword0_raw;
error = (qword1 & I40E_RX_PROG_STATUS_DESC_QW1_ERROR_MASK) >>
I40E_RX_PROG_STATUS_DESC_QW1_ERROR_SHIFT;

Expand Down Expand Up @@ -1418,7 +1418,7 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring)
u64_stats_init(&rx_ring->syncp);

/* Round up to nearest 4K */
rx_ring->size = rx_ring->count * sizeof(union i40e_32byte_rx_desc);
rx_ring->size = rx_ring->count * sizeof(union i40e_rx_desc);
rx_ring->size = ALIGN(rx_ring->size, 4096);
rx_ring->desc = dma_alloc_coherent(dev, rx_ring->size,
&rx_ring->dma, GFP_KERNEL);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/i40e/i40e_txrx.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ enum i40e_dyn_idx_t {
*/
#define I40E_RX_HDR_SIZE I40E_RXBUFFER_256
#define I40E_PACKET_HDR_PAD (ETH_HLEN + ETH_FCS_LEN + (VLAN_HLEN * 2))
#define i40e_rx_desc i40e_32byte_rx_desc
#define i40e_rx_desc i40e_16byte_rx_desc

#define I40E_RX_DMA_ATTR \
(DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING)
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/intel/i40e/i40e_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ union i40e_16byte_rx_desc {
__le64 hdr_addr; /* Header buffer address */
} read;
struct {
struct {
struct i40e_16b_rx_wb_qw0 {
struct {
union {
__le16 mirroring_status;
Expand All @@ -647,6 +647,9 @@ union i40e_16byte_rx_desc {
__le64 status_error_len;
} qword1;
} wb; /* writeback */
struct {
u64 qword[2];
} raw;
};

union i40e_32byte_rx_desc {
Expand Down

0 comments on commit f0064bf

Please sign in to comment.