diff options
author | David S. Miller <davem@davemloft.net> | 2014-03-26 02:54:36 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-26 02:54:36 +0400 |
commit | 8779772c93286fcfe8ab428dc83434c783225535 (patch) | |
tree | 2e259136fe391a5068bec0ea7f1e8d75e0cf7800 /drivers/net/ethernet/atheros | |
parent | 35d499ee3a63b645f355d98dc407b22751896a43 (diff) | |
parent | fb7c03dfc48eb81bda368561f4ca162749d127c9 (diff) | |
download | linux-8779772c93286fcfe8ab428dc83434c783225535.tar.xz |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/net-next
Eric W. Biederman says:
====================
Using dev_kfree/consume_skb_any for functions called in multiple contexts
These changes are a result of walking through the network drivers
supporting netpoll and verifying the code paths that netpoll can cause
to be called in hard irq context use an appropriate flavor of
kfree_skb. Either dev_kfree_skb_any or dev_consume_skb_any.
Since my last pass at this I have become aware of the small differences
between dev_kfree_skb_any and dev_consume_skb_any.
net/core/drop_monitor.c reports the dev_kfree_skb_any as a drop and
while being quite about the second. With the weird twist that
dev_kfree_skb is unintuitively consume_skb.
As netpoll now calls the napi poll function with budget == 0, pieces of
a drivers the napi poll function that don't run when budget == 0 have
been ignored.
The most interesting change is to the atl1c which tried unsuccesfully to
tell one of it's functions which context it is called in so that it
could call dev_kfree_skb_irq or dev_kfree_skb as appropriate. I have
just removed the extra parameter and called dev_consume_skb_any.
At 54 separate changes I will post each change as a separate patch (so
they can be reviewed) but for general sanity sake I have gathered them
all into a git branch for easy acces.
====================
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/atheros')
-rw-r--r-- | drivers/net/ethernet/atheros/alx/main.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 20 |
2 files changed, 9 insertions, 13 deletions
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index 2e45f6ec1bf0..238356108e65 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c @@ -1097,7 +1097,7 @@ static netdev_tx_t alx_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; drop: - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); return NETDEV_TX_OK; } diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 4d3258dd0a88..31f262302128 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -832,7 +832,7 @@ static int atl1c_sw_init(struct atl1c_adapter *adapter) } static inline void atl1c_clean_buffer(struct pci_dev *pdev, - struct atl1c_buffer *buffer_info, int in_irq) + struct atl1c_buffer *buffer_info) { u16 pci_driection; if (buffer_info->flags & ATL1C_BUFFER_FREE) @@ -850,12 +850,8 @@ static inline void atl1c_clean_buffer(struct pci_dev *pdev, pci_unmap_page(pdev, buffer_info->dma, buffer_info->length, pci_driection); } - if (buffer_info->skb) { - if (in_irq) - dev_kfree_skb_irq(buffer_info->skb); - else - dev_kfree_skb(buffer_info->skb); - } + if (buffer_info->skb) + dev_consume_skb_any(buffer_info->skb); buffer_info->dma = 0; buffer_info->skb = NULL; ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE); @@ -875,7 +871,7 @@ static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter, ring_count = tpd_ring->count; for (index = 0; index < ring_count; index++) { buffer_info = &tpd_ring->buffer_info[index]; - atl1c_clean_buffer(pdev, buffer_info, 0); + atl1c_clean_buffer(pdev, buffer_info); } /* Zero out Tx-buffers */ @@ -899,7 +895,7 @@ static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter) for (j = 0; j < rfd_ring->count; j++) { buffer_info = &rfd_ring->buffer_info[j]; - atl1c_clean_buffer(pdev, buffer_info, 0); + atl1c_clean_buffer(pdev, buffer_info); } /* zero out the descriptor ring */ memset(rfd_ring->desc, 0, rfd_ring->size); @@ -1562,7 +1558,7 @@ static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter, while (next_to_clean != hw_next_to_clean) { buffer_info = &tpd_ring->buffer_info[next_to_clean]; - atl1c_clean_buffer(pdev, buffer_info, 1); + atl1c_clean_buffer(pdev, buffer_info); if (++next_to_clean == tpd_ring->count) next_to_clean = 0; atomic_set(&tpd_ring->next_to_clean, next_to_clean); @@ -2085,7 +2081,7 @@ static void atl1c_tx_rollback(struct atl1c_adapter *adpt, while (index != tpd_ring->next_to_use) { tpd = ATL1C_TPD_DESC(tpd_ring, index); buffer_info = &tpd_ring->buffer_info[index]; - atl1c_clean_buffer(adpt->pdev, buffer_info, 0); + atl1c_clean_buffer(adpt->pdev, buffer_info); memset(tpd, 0, sizeof(struct atl1c_tpd_desc)); if (++index == tpd_ring->count) index = 0; @@ -2258,7 +2254,7 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb, /* roll back tpd/buffer */ atl1c_tx_rollback(adapter, tpd, type); spin_unlock_irqrestore(&adapter->tx_lock, flags); - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); } else { atl1c_tx_queue(adapter, skb, tpd, type); spin_unlock_irqrestore(&adapter->tx_lock, flags); |