* [RFC 0/5] generic rx recycling
@ 2010-05-05 14:47 Sebastian Andrzej Siewior
2010-05-05 14:47 ` [RFC 1/5] net: implement " Sebastian Andrzej Siewior
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-05-05 14:47 UTC (permalink / raw)
To: netdev; +Cc: tglx
This series merges the rx recycling code trying to come up with generic
code. Recycling skbs from the tx path for incomming rx skips the memory
allocater and improves latency during memory pressure.
This is now used by just by just four drivers in the tree which were doing
this on their own.
Sebastian
^ permalink raw reply [flat|nested] 7+ messages in thread
* [RFC 1/5] net: implement generic rx recycling
2010-05-05 14:47 [RFC 0/5] generic rx recycling Sebastian Andrzej Siewior
@ 2010-05-05 14:47 ` Sebastian Andrzej Siewior
2010-05-05 14:47 ` [RFC 2/5] net/gianfar: use generic recycling infrasstructure Sebastian Andrzej Siewior
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-05-05 14:47 UTC (permalink / raw)
To: netdev; +Cc: tglx, Sebastian Andrzej Siewior
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
include/linux/netdevice.h | 70 +++++++++++++++++++++++++++++++++++++--------
1 files changed, 58 insertions(+), 12 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 98112fb..70d385d 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -588,6 +588,18 @@ struct netdev_rx_queue {
} ____cacheline_aligned_in_smp;
#endif /* CONFIG_RPS */
+/* Use this variant when it is known for sure that it
+ * is executing from hardware interrupt context or with hardware interrupts
+ * disabled.
+ */
+extern void dev_kfree_skb_irq(struct sk_buff *skb);
+
+/* Use this variant in places where it could be invoked
+ * from either hardware interrupt or other context, with hardware interrupts
+ * either disabled or enabled.
+ */
+extern void dev_kfree_skb_any(struct sk_buff *skb);
+
/*
* This structure defines the management hooks for network devices.
* The following hooks can be defined; unless noted otherwise, they are
@@ -1044,9 +1056,55 @@ struct net_device {
#endif
/* n-tuple filter list attached to this device */
struct ethtool_rx_ntuple_list ethtool_ntuple_list;
+ struct sk_buff_head rx_recycle;
+ u32 rx_rec_skbs_max;
+ u32 rx_rec_skb_size;
};
#define to_net_dev(d) container_of(d, struct net_device, dev)
+static inline void net_recycle_init(struct net_device *dev, u32 qlen, u32 size)
+{
+ skb_queue_head_init(&dev->rx_recycle);
+ dev->rx_rec_skbs_max = qlen;
+ dev->rx_rec_skb_size = size;
+}
+
+static inline void net_recycle_cleanup(struct net_device *dev)
+{
+ skb_queue_purge(&dev->rx_recycle);
+}
+
+static inline void net_recycle_add(struct net_device *dev, struct sk_buff *skb)
+{
+ if (skb_queue_len(&dev->rx_recycle) < dev->rx_rec_skbs_max &&
+ skb_recycle_check(skb, dev->rx_rec_skb_size))
+ skb_queue_head(&dev->rx_recycle, skb);
+ else
+ dev_kfree_skb_any(skb);
+}
+
+static inline struct sk_buff *net_recycle_get(struct net_device *dev)
+{
+ struct sk_buff *skb;
+
+ skb = skb_dequeue(&dev->rx_recycle);
+ if (skb)
+ return skb;
+ return netdev_alloc_skb(dev, dev->rx_rec_skb_size);
+}
+
+static inline void net_recycle_size(struct net_device *dev, u32 size)
+{
+ if (dev->rx_rec_skb_size < size)
+ net_recycle_cleanup(dev);
+ dev->rx_rec_skb_size = size;
+}
+
+static inline void net_recycle_qlen(struct net_device *dev, u32 qlen)
+{
+ dev->rx_rec_skbs_max = qlen;
+}
+
#define NETDEV_ALIGN 32
static inline
@@ -1635,18 +1693,6 @@ static inline int netif_is_multiqueue(const struct net_device *dev)
return (dev->num_tx_queues > 1);
}
-/* Use this variant when it is known for sure that it
- * is executing from hardware interrupt context or with hardware interrupts
- * disabled.
- */
-extern void dev_kfree_skb_irq(struct sk_buff *skb);
-
-/* Use this variant in places where it could be invoked
- * from either hardware interrupt or other context, with hardware interrupts
- * either disabled or enabled.
- */
-extern void dev_kfree_skb_any(struct sk_buff *skb);
-
#define HAVE_NETIF_RX 1
extern int netif_rx(struct sk_buff *skb);
extern int netif_rx_ni(struct sk_buff *skb);
--
1.6.6.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [RFC 2/5] net/gianfar: use generic recycling infrasstructure
2010-05-05 14:47 [RFC 0/5] generic rx recycling Sebastian Andrzej Siewior
2010-05-05 14:47 ` [RFC 1/5] net: implement " Sebastian Andrzej Siewior
@ 2010-05-05 14:47 ` Sebastian Andrzej Siewior
2010-05-05 14:47 ` [RFC 3/5] net/mv643xx: use generic recycling infrastructure Sebastian Andrzej Siewior
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-05-05 14:47 UTC (permalink / raw)
To: netdev; +Cc: tglx, Sebastian Andrzej Siewior
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
drivers/net/gianfar.c | 28 ++++++++--------------------
drivers/net/gianfar.h | 2 --
2 files changed, 8 insertions(+), 22 deletions(-)
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index c6df2ba..af98675 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1102,6 +1102,9 @@ static int gfar_probe(struct of_device *ofdev,
priv->rx_queue[i]->rxic = DEFAULT_RXIC;
}
+ net_recycle_init(dev, DEFAULT_RX_RING_SIZE,
+ priv->rx_buffer_size + RXBUF_ALIGNMENT);
+
/* enable filer if using multiple RX queues*/
if(priv->num_rx_queues > 1)
priv->rx_filer_enable = 1;
@@ -1705,7 +1708,7 @@ static void free_skb_resources(struct gfar_private *priv)
sizeof(struct rxbd8) * priv->total_rx_ring_size,
priv->tx_queue[0]->tx_bd_base,
priv->tx_queue[0]->tx_bd_dma_base);
- skb_queue_purge(&priv->rx_recycle);
+ net_recycle_cleanup(priv->ndev);
}
void gfar_start(struct net_device *dev)
@@ -1886,8 +1889,6 @@ static int gfar_enet_open(struct net_device *dev)
enable_napi(priv);
- skb_queue_head_init(&priv->rx_recycle);
-
/* Initialize a bunch of registers */
init_registers(dev);
@@ -2291,6 +2292,7 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
stop_gfar(dev);
priv->rx_buffer_size = tempsize;
+ net_recycle_size(dev, tempsize + RXBUF_ALIGNMENT);
dev->mtu = new_mtu;
@@ -2422,16 +2424,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
bdp = next_txbd(bdp, base, tx_ring_size);
}
- /*
- * If there's room in the queue (limit it to rx_buffer_size)
- * we add this skb back into the pool, if it's the right size
- */
- if (skb_queue_len(&priv->rx_recycle) < rx_queue->rx_ring_size &&
- skb_recycle_check(skb, priv->rx_buffer_size +
- RXBUF_ALIGNMENT))
- __skb_queue_head(&priv->rx_recycle, skb);
- else
- dev_kfree_skb_any(skb);
+ net_recycle_add(dev, skb);
tx_queue->tx_skbuff[skb_dirtytx] = NULL;
@@ -2497,14 +2490,9 @@ static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp,
struct sk_buff * gfar_new_skb(struct net_device *dev)
{
unsigned int alignamount;
- struct gfar_private *priv = netdev_priv(dev);
struct sk_buff *skb = NULL;
- skb = __skb_dequeue(&priv->rx_recycle);
- if (!skb)
- skb = netdev_alloc_skb(dev,
- priv->rx_buffer_size + RXBUF_ALIGNMENT);
-
+ skb = net_recycle_get(dev);
if (!skb)
return NULL;
@@ -2673,7 +2661,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)
* recycle list.
*/
skb_reserve(skb, -GFAR_CB(skb)->alignamount);
- __skb_queue_head(&priv->rx_recycle, skb);
+ net_recycle_add(dev, skb);
}
} else {
/* Increment the number of packets */
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index ac4a92e..99f5a9b 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -1061,8 +1061,6 @@ struct gfar_private {
u32 cur_filer_idx;
- struct sk_buff_head rx_recycle;
-
struct vlan_group *vlgrp;
--
1.6.6.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [RFC 3/5] net/mv643xx: use generic recycling infrastructure
2010-05-05 14:47 [RFC 0/5] generic rx recycling Sebastian Andrzej Siewior
2010-05-05 14:47 ` [RFC 1/5] net: implement " Sebastian Andrzej Siewior
2010-05-05 14:47 ` [RFC 2/5] net/gianfar: use generic recycling infrasstructure Sebastian Andrzej Siewior
@ 2010-05-05 14:47 ` Sebastian Andrzej Siewior
2010-05-05 14:47 ` [RFC 4/5] net/stmmac: " Sebastian Andrzej Siewior
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-05-05 14:47 UTC (permalink / raw)
To: netdev; +Cc: tglx, Sebastian Andrzej Siewior
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
drivers/net/mv643xx_eth.c | 27 +++++++++------------------
1 files changed, 9 insertions(+), 18 deletions(-)
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 4ee9d04..f56aaac 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -404,8 +404,6 @@ struct mv643xx_eth_private {
u8 work_rx_refill;
int skb_size;
- struct sk_buff_head rx_recycle;
-
/*
* RX state.
*/
@@ -649,6 +647,7 @@ err:
static int rxq_refill(struct rx_queue *rxq, int budget)
{
struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
+ struct net_device *dev = mp->dev;
int refilled;
refilled = 0;
@@ -658,10 +657,7 @@ static int rxq_refill(struct rx_queue *rxq, int budget)
struct rx_desc *rx_desc;
int size;
- skb = __skb_dequeue(&mp->rx_recycle);
- if (skb == NULL)
- skb = dev_alloc_skb(mp->skb_size);
-
+ skb = net_recycle_get(dev);
if (skb == NULL) {
mp->oom = 1;
goto oom;
@@ -922,6 +918,7 @@ out:
static int txq_reclaim(struct tx_queue *txq, int budget, int force)
{
struct mv643xx_eth_private *mp = txq_to_mp(txq);
+ struct net_device *dev = mp->dev;
struct netdev_queue *nq = netdev_get_tx_queue(mp->dev, txq->index);
int reclaimed;
@@ -968,14 +965,8 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force)
desc->byte_cnt, DMA_TO_DEVICE);
}
- if (skb != NULL) {
- if (skb_queue_len(&mp->rx_recycle) <
- mp->rx_ring_size &&
- skb_recycle_check(skb, mp->skb_size))
- __skb_queue_head(&mp->rx_recycle, skb);
- else
- dev_kfree_skb(skb);
- }
+ if (skb)
+ net_recycle_add(dev, skb);
}
__netif_tx_unlock(nq);
@@ -1564,7 +1555,7 @@ mv643xx_eth_set_ringparam(struct net_device *dev, struct ethtool_ringparam *er)
mp->rx_ring_size = er->rx_pending < 4096 ? er->rx_pending : 4096;
mp->tx_ring_size = er->tx_pending < 4096 ? er->tx_pending : 4096;
-
+ net_recycle_qlen(dev, mp->rx_ring_size);
if (netif_running(dev)) {
mv643xx_eth_stop(dev);
if (mv643xx_eth_open(dev)) {
@@ -2340,9 +2331,9 @@ static int mv643xx_eth_open(struct net_device *dev)
mv643xx_eth_recalc_skb_size(mp);
- napi_enable(&mp->napi);
+ net_recycle_init(mp->dev, mp->rx_ring_size, mp->skb_size);
- skb_queue_head_init(&mp->rx_recycle);
+ napi_enable(&mp->napi);
mp->int_mask = INT_EXT;
@@ -2438,7 +2429,7 @@ static int mv643xx_eth_stop(struct net_device *dev)
mib_counters_update(mp);
del_timer_sync(&mp->mib_counters_timer);
- skb_queue_purge(&mp->rx_recycle);
+ net_recycle_cleanup(dev);
for (i = 0; i < mp->rxq_count; i++)
rxq_deinit(mp->rxq + i);
--
1.6.6.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [RFC 4/5] net/stmmac: use generic recycling infrastructure
2010-05-05 14:47 [RFC 0/5] generic rx recycling Sebastian Andrzej Siewior
` (2 preceding siblings ...)
2010-05-05 14:47 ` [RFC 3/5] net/mv643xx: use generic recycling infrastructure Sebastian Andrzej Siewior
@ 2010-05-05 14:47 ` Sebastian Andrzej Siewior
2010-05-05 14:47 ` [RFC 5/5] net/ucc_geth: " Sebastian Andrzej Siewior
2010-05-16 6:32 ` [RFC 0/5] generic rx recycling David Miller
5 siblings, 0 replies; 7+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-05-05 14:47 UTC (permalink / raw)
To: netdev; +Cc: tglx, Sebastian Andrzej Siewior
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
drivers/net/stmmac/stmmac.h | 1 -
drivers/net/stmmac/stmmac_main.c | 26 +++++++-------------------
2 files changed, 7 insertions(+), 20 deletions(-)
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h
index ebebc64..dbf9f95 100644
--- a/drivers/net/stmmac/stmmac.h
+++ b/drivers/net/stmmac/stmmac.h
@@ -44,7 +44,6 @@ struct stmmac_priv {
unsigned int dirty_rx;
struct sk_buff **rx_skbuff;
dma_addr_t *rx_skbuff_dma;
- struct sk_buff_head rx_recycle;
struct net_device *dev;
int is_gmac;
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index 7ac6dde..14c4e25 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -646,18 +646,7 @@ static void stmmac_tx(struct stmmac_priv *priv)
p->des3 = 0;
if (likely(skb != NULL)) {
- /*
- * If there's room in the queue (limit it to size)
- * we add this skb back into the pool,
- * if it's the right size.
- */
- if ((skb_queue_len(&priv->rx_recycle) <
- priv->dma_rx_size) &&
- skb_recycle_check(skb, priv->dma_buf_sz))
- __skb_queue_head(&priv->rx_recycle, skb);
- else
- dev_kfree_skb(skb);
-
+ net_recycle_add(priv->dev, skb);
priv->tx_skbuff[entry] = NULL;
}
@@ -860,6 +849,9 @@ static int stmmac_open(struct net_device *dev)
priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
init_dma_desc_rings(dev);
+ net_recycle_init(priv->dev, priv->dma_rx_size, priv->dma_buf_sz +
+ NET_IP_ALIGN);
+
/* DMA initialization and SW reset */
if (unlikely(priv->hw->dma->init(ioaddr, priv->pbl, priv->dma_tx_phy,
priv->dma_rx_phy) < 0)) {
@@ -911,7 +903,6 @@ static int stmmac_open(struct net_device *dev)
phy_start(priv->phydev);
napi_enable(&priv->napi);
- skb_queue_head_init(&priv->rx_recycle);
netif_start_queue(dev);
return 0;
}
@@ -942,7 +933,7 @@ static int stmmac_release(struct net_device *dev)
kfree(priv->tm);
#endif
napi_disable(&priv->napi);
- skb_queue_purge(&priv->rx_recycle);
+ net_recycle_cleanup(priv->dev);
/* Free the IRQ lines */
free_irq(dev->irq, dev);
@@ -1174,13 +1165,10 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv)
if (likely(priv->rx_skbuff[entry] == NULL)) {
struct sk_buff *skb;
- skb = __skb_dequeue(&priv->rx_recycle);
- if (skb == NULL)
- skb = netdev_alloc_skb_ip_align(priv->dev,
- bfsize);
-
+ skb = net_recycle_get(priv->dev);
if (unlikely(skb == NULL))
break;
+ skb_reserve(skb, NET_IP_ALIGN);
priv->rx_skbuff[entry] = skb;
priv->rx_skbuff_dma[entry] =
--
1.6.6.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [RFC 5/5] net/ucc_geth: use generic recycling infrastructure
2010-05-05 14:47 [RFC 0/5] generic rx recycling Sebastian Andrzej Siewior
` (3 preceding siblings ...)
2010-05-05 14:47 ` [RFC 4/5] net/stmmac: " Sebastian Andrzej Siewior
@ 2010-05-05 14:47 ` Sebastian Andrzej Siewior
2010-05-16 6:32 ` [RFC 0/5] generic rx recycling David Miller
5 siblings, 0 replies; 7+ messages in thread
From: Sebastian Andrzej Siewior @ 2010-05-05 14:47 UTC (permalink / raw)
To: netdev; +Cc: tglx, Sebastian Andrzej Siewior
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
drivers/net/ucc_geth.c | 24 +++++++-----------------
drivers/net/ucc_geth.h | 2 --
2 files changed, 7 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 081f76b..d5af4f1 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -210,10 +210,7 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth,
{
struct sk_buff *skb = NULL;
- skb = __skb_dequeue(&ugeth->rx_recycle);
- if (!skb)
- skb = dev_alloc_skb(ugeth->ug_info->uf_info.max_rx_buf_length +
- UCC_GETH_RX_DATA_BUF_ALIGNMENT);
+ skb = net_recycle_get(ugeth->ndev);
if (skb == NULL)
return NULL;
@@ -1992,8 +1989,6 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth)
iounmap(ugeth->ug_regs);
ugeth->ug_regs = NULL;
}
-
- skb_queue_purge(&ugeth->rx_recycle);
}
static void ucc_geth_set_multi(struct net_device *dev)
@@ -2069,6 +2064,7 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
ugeth->phydev = NULL;
ucc_geth_memclean(ugeth);
+ net_recycle_cleanup(ugeth->ndev);
}
static int ucc_struct_init(struct ucc_geth_private *ugeth)
@@ -2205,9 +2201,6 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
ugeth_err("%s: Failed to ioremap regs.", __func__);
return -ENOMEM;
}
-
- skb_queue_head_init(&ugeth->rx_recycle);
-
return 0;
}
@@ -3217,7 +3210,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
__func__, __LINE__, (u32) skb);
if (skb) {
skb->data = skb->head + NET_SKB_PAD;
- __skb_queue_head(&ugeth->rx_recycle, skb);
+ net_recycle_add(dev, skb);
}
ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]] = NULL;
@@ -3288,13 +3281,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
dev->stats.tx_packets++;
- if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN &&
- skb_recycle_check(skb,
- ugeth->ug_info->uf_info.max_rx_buf_length +
- UCC_GETH_RX_DATA_BUF_ALIGNMENT))
- __skb_queue_head(&ugeth->rx_recycle, skb);
- else
- dev_kfree_skb(skb);
+ net_recycle_add(dev, skb);
ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL;
ugeth->skb_dirtytx[txQ] =
@@ -3915,6 +3902,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, 64);
dev->mtu = 1500;
+ net_recycle_init(dev, RX_BD_RING_LEN, ug_info->uf_info.max_rx_buf_length
+ + UCC_GETH_RX_DATA_BUF_ALIGNMENT);
+
ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT);
ugeth->phy_interface = phy_interface;
ugeth->max_speed = max_speed;
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index ef1fbeb..55708c5 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -1213,8 +1213,6 @@ struct ucc_geth_private {
/* index of the first skb which hasn't been transmitted yet. */
u16 skb_dirtytx[NUM_TX_QUEUES];
- struct sk_buff_head rx_recycle;
-
struct ugeth_mii_info *mii_info;
struct phy_device *phydev;
phy_interface_t phy_interface;
--
1.6.6.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [RFC 0/5] generic rx recycling
2010-05-05 14:47 [RFC 0/5] generic rx recycling Sebastian Andrzej Siewior
` (4 preceding siblings ...)
2010-05-05 14:47 ` [RFC 5/5] net/ucc_geth: " Sebastian Andrzej Siewior
@ 2010-05-16 6:32 ` David Miller
5 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2010-05-16 6:32 UTC (permalink / raw)
To: sebastian; +Cc: netdev, tglx
From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Date: Wed, 5 May 2010 16:47:45 +0200
> This series merges the rx recycling code trying to come up with generic
> code. Recycling skbs from the tx path for incomming rx skips the memory
> allocater and improves latency during memory pressure.
> This is now used by just by just four drivers in the tree which were doing
> this on their own.
You're adding new unnecessary SMP locking to all of these drivers.
In the gianfar original code the recycle queue is accessed lockless
using __skb_dequeue() et al. But you're using the skb_dequeue()
interface in the generic version which takes the SKB queue lock
which is absolutely unnecessary where these drivers make these
calls since they already need to have their chip RX path locked
already.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2010-05-16 6:32 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-05 14:47 [RFC 0/5] generic rx recycling Sebastian Andrzej Siewior
2010-05-05 14:47 ` [RFC 1/5] net: implement " Sebastian Andrzej Siewior
2010-05-05 14:47 ` [RFC 2/5] net/gianfar: use generic recycling infrasstructure Sebastian Andrzej Siewior
2010-05-05 14:47 ` [RFC 3/5] net/mv643xx: use generic recycling infrastructure Sebastian Andrzej Siewior
2010-05-05 14:47 ` [RFC 4/5] net/stmmac: " Sebastian Andrzej Siewior
2010-05-05 14:47 ` [RFC 5/5] net/ucc_geth: " Sebastian Andrzej Siewior
2010-05-16 6:32 ` [RFC 0/5] generic rx recycling David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).