mirror of https://gitee.com/openkylin/linux.git
net: aquantia: optimize rx path using larger preallocated skb len
Atlantic driver used 14 bytes preallocated skb size. That made L3 protocol processing inefficient because pskb_pull had to fetch all the L3/L4 headers from extra fragments. Specially on UDP flows that caused extra packet drops because CPU was overloaded with pskb_pull. This patch uses eth_get_headlen for skb preallocation. Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d64fee0a03
commit
7e2698c4fd
|
@ -38,6 +38,8 @@
|
|||
|
||||
#define AQ_CFG_TX_CLEAN_BUDGET 256U
|
||||
|
||||
#define AQ_CFG_RX_HDR_SIZE 256U
|
||||
|
||||
/* LRO */
|
||||
#define AQ_CFG_IS_LRO_DEF 1U
|
||||
|
||||
|
|
|
@ -201,17 +201,18 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
|
|||
int budget)
|
||||
{
|
||||
struct net_device *ndev = aq_nic_get_ndev(self->aq_nic);
|
||||
int err = 0;
|
||||
bool is_rsc_completed = true;
|
||||
int err = 0;
|
||||
|
||||
for (; (self->sw_head != self->hw_head) && budget;
|
||||
self->sw_head = aq_ring_next_dx(self, self->sw_head),
|
||||
--budget, ++(*work_done)) {
|
||||
struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head];
|
||||
struct aq_ring_buff_s *buff_ = NULL;
|
||||
struct sk_buff *skb = NULL;
|
||||
unsigned int next_ = 0U;
|
||||
unsigned int i = 0U;
|
||||
struct aq_ring_buff_s *buff_ = NULL;
|
||||
u16 hdr_len;
|
||||
|
||||
if (buff->is_error) {
|
||||
__free_pages(buff->page, 0);
|
||||
|
@ -255,20 +256,28 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
|
|||
err = -ENOMEM;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
skb_put(skb, buff->len);
|
||||
} else {
|
||||
skb = netdev_alloc_skb(ndev, ETH_HLEN);
|
||||
skb = napi_alloc_skb(napi, AQ_CFG_RX_HDR_SIZE);
|
||||
if (unlikely(!skb)) {
|
||||
err = -ENOMEM;
|
||||
goto err_exit;
|
||||
}
|
||||
skb_put(skb, ETH_HLEN);
|
||||
memcpy(skb->data, page_address(buff->page), ETH_HLEN);
|
||||
|
||||
skb_add_rx_frag(skb, 0, buff->page, ETH_HLEN,
|
||||
buff->len - ETH_HLEN,
|
||||
SKB_TRUESIZE(buff->len - ETH_HLEN));
|
||||
hdr_len = buff->len;
|
||||
if (hdr_len > AQ_CFG_RX_HDR_SIZE)
|
||||
hdr_len = eth_get_headlen(page_address(buff->page),
|
||||
AQ_CFG_RX_HDR_SIZE);
|
||||
|
||||
memcpy(__skb_put(skb, hdr_len), page_address(buff->page),
|
||||
ALIGN(hdr_len, sizeof(long)));
|
||||
|
||||
if (buff->len - hdr_len > 0) {
|
||||
skb_add_rx_frag(skb, 0, buff->page,
|
||||
hdr_len,
|
||||
buff->len - hdr_len,
|
||||
SKB_TRUESIZE(buff->len - hdr_len));
|
||||
}
|
||||
|
||||
if (!buff->is_eop) {
|
||||
for (i = 1U, next_ = buff->next,
|
||||
|
|
Loading…
Reference in New Issue