All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 net-next 0/7] Avoid local_irq_save() and use napi_alloc_frag() where possible
@ 2019-06-07 19:20 Sebastian Andrzej Siewior
  2019-06-07 19:20 ` [PATCH v2 net-next 1/7] net: Don't disable interrupts in napi_alloc_frag() Sebastian Andrzej Siewior
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Sebastian Andrzej Siewior @ 2019-06-07 19:20 UTC (permalink / raw)
  To: netdev; +Cc: tglx, David S. Miller

The first two patches remove local_irq_save() around
`netdev_alloc_cache' which does not work on -RT. Besides helping -RT it
whould benefit the users of the function since they can avoid disabling
interrupts and save a few cycles.
The remaining patches are from a time when I tried to remove
`netdev_alloc_cache' but then noticed that we still have non-NAPI
drivers using netdev_alloc_skb() and I dropped that idea. Using
napi_alloc_frag() over netdev_alloc_frag() would skip the not required
local_bh_disable() around the allocation.

v1…v2:
  - 1/7 + 2/7 use now "(in_irq() || irqs_disabled())" instead just
    "irqs_disabled()" to align with __dev_kfree_skb_any(). Pointed out
    by Eric Dumazet.

  - 6/7 has a typo less. Pointed out by Sergei Shtylyov.

  - 3/7 + 4/7 added acks from Ioana Radulescu.

Sebastian



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 net-next 1/7] net: Don't disable interrupts in napi_alloc_frag()
  2019-06-07 19:20 [PATCH v2 net-next 0/7] Avoid local_irq_save() and use napi_alloc_frag() where possible Sebastian Andrzej Siewior
@ 2019-06-07 19:20 ` Sebastian Andrzej Siewior
  2019-06-07 19:20 ` [PATCH v2 net-next 2/7] net: Don't disable interrupts in __netdev_alloc_skb() Sebastian Andrzej Siewior
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sebastian Andrzej Siewior @ 2019-06-07 19:20 UTC (permalink / raw)
  To: netdev; +Cc: tglx, David S. Miller, Sebastian Andrzej Siewior

netdev_alloc_frag() can be used from any context and is used by NAPI
and non-NAPI drivers. Non-NAPI drivers use it in interrupt context
and NAPI drivers use it during initial allocation (->ndo_open() or
->ndo_change_mtu()). Some NAPI drivers share the same function for the
initial allocation and the allocation in their NAPI callback.

The interrupts are disabled in order to ensure locked access from every
context to `netdev_alloc_cache'.

Let netdev_alloc_frag() check if interrupts are disabled. If they are,
use `netdev_alloc_cache' otherwise disable BH and invoke
__napi_alloc_frag() for the allocation. The IRQ check is cheaper
compared to disabling & enabling interrupts and memory allocation with
disabled interrupts does not work on -RT.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 net/core/skbuff.c | 53 ++++++++++++++++++++++-------------------------
 1 file changed, 25 insertions(+), 28 deletions(-)

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 47c1aa9ee0454..e246120bdd1b4 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -365,34 +365,6 @@ struct napi_alloc_cache {
 static DEFINE_PER_CPU(struct page_frag_cache, netdev_alloc_cache);
 static DEFINE_PER_CPU(struct napi_alloc_cache, napi_alloc_cache);
 
-static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask)
-{
-	struct page_frag_cache *nc;
-	unsigned long flags;
-	void *data;
-
-	local_irq_save(flags);
-	nc = this_cpu_ptr(&netdev_alloc_cache);
-	data = page_frag_alloc(nc, fragsz, gfp_mask);
-	local_irq_restore(flags);
-	return data;
-}
-
-/**
- * netdev_alloc_frag - allocate a page fragment
- * @fragsz: fragment size
- *
- * Allocates a frag from a page for receive buffer.
- * Uses GFP_ATOMIC allocations.
- */
-void *netdev_alloc_frag(unsigned int fragsz)
-{
-	fragsz = SKB_DATA_ALIGN(fragsz);
-
-	return __netdev_alloc_frag(fragsz, GFP_ATOMIC);
-}
-EXPORT_SYMBOL(netdev_alloc_frag);
-
 static void *__napi_alloc_frag(unsigned int fragsz, gfp_t gfp_mask)
 {
 	struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache);
@@ -408,6 +380,31 @@ void *napi_alloc_frag(unsigned int fragsz)
 }
 EXPORT_SYMBOL(napi_alloc_frag);
 
+/**
+ * netdev_alloc_frag - allocate a page fragment
+ * @fragsz: fragment size
+ *
+ * Allocates a frag from a page for receive buffer.
+ * Uses GFP_ATOMIC allocations.
+ */
+void *netdev_alloc_frag(unsigned int fragsz)
+{
+	struct page_frag_cache *nc;
+	void *data;
+
+	fragsz = SKB_DATA_ALIGN(fragsz);
+	if (in_irq() || irqs_disabled()) {
+		nc = this_cpu_ptr(&netdev_alloc_cache);
+		data = page_frag_alloc(nc, fragsz, GFP_ATOMIC);
+	} else {
+		local_bh_disable();
+		data = __napi_alloc_frag(fragsz, GFP_ATOMIC);
+		local_bh_enable();
+	}
+	return data;
+}
+EXPORT_SYMBOL(netdev_alloc_frag);
+
 /**
  *	__netdev_alloc_skb - allocate an skbuff for rx on a specific device
  *	@dev: network device to receive on
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 net-next 2/7] net: Don't disable interrupts in __netdev_alloc_skb()
  2019-06-07 19:20 [PATCH v2 net-next 0/7] Avoid local_irq_save() and use napi_alloc_frag() where possible Sebastian Andrzej Siewior
  2019-06-07 19:20 ` [PATCH v2 net-next 1/7] net: Don't disable interrupts in napi_alloc_frag() Sebastian Andrzej Siewior
@ 2019-06-07 19:20 ` Sebastian Andrzej Siewior
  2019-06-07 19:20 ` [PATCH v2 net-next 3/7] dpaa2-eth: Remove preempt_disable() from seed_pool() Sebastian Andrzej Siewior
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sebastian Andrzej Siewior @ 2019-06-07 19:20 UTC (permalink / raw)
  To: netdev; +Cc: tglx, David S. Miller, Sebastian Andrzej Siewior

__netdev_alloc_skb() can be used from any context and is used by NAPI
and non-NAPI drivers. Non-NAPI drivers use it in interrupt context and
NAPI drivers use it during initial allocation (->ndo_open() or
->ndo_change_mtu()). Some NAPI drivers share the same function for the
initial allocation and the allocation in their NAPI callback.

The interrupts are disabled in order to ensure locked access from every
context to `netdev_alloc_cache'.

Let __netdev_alloc_skb() check if interrupts are disabled. If they are, use
`netdev_alloc_cache'. Otherwise disable BH and use `napi_alloc_cache.page'.
The IRQ check is cheaper compared to disabling & enabling interrupts and
memory allocation with disabled interrupts does not work on -RT.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 net/core/skbuff.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index e246120bdd1b4..c7680f0b64c3b 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -422,7 +422,6 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len,
 				   gfp_t gfp_mask)
 {
 	struct page_frag_cache *nc;
-	unsigned long flags;
 	struct sk_buff *skb;
 	bool pfmemalloc;
 	void *data;
@@ -443,13 +442,17 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len,
 	if (sk_memalloc_socks())
 		gfp_mask |= __GFP_MEMALLOC;
 
-	local_irq_save(flags);
-
-	nc = this_cpu_ptr(&netdev_alloc_cache);
-	data = page_frag_alloc(nc, len, gfp_mask);
-	pfmemalloc = nc->pfmemalloc;
-
-	local_irq_restore(flags);
+	if (in_irq() || irqs_disabled()) {
+		nc = this_cpu_ptr(&netdev_alloc_cache);
+		data = page_frag_alloc(nc, len, gfp_mask);
+		pfmemalloc = nc->pfmemalloc;
+	} else {
+		local_bh_disable();
+		nc = this_cpu_ptr(&napi_alloc_cache.page);
+		data = page_frag_alloc(nc, len, gfp_mask);
+		pfmemalloc = nc->pfmemalloc;
+		local_bh_enable();
+	}
 
 	if (unlikely(!data))
 		return NULL;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 net-next 3/7] dpaa2-eth: Remove preempt_disable() from seed_pool()
  2019-06-07 19:20 [PATCH v2 net-next 0/7] Avoid local_irq_save() and use napi_alloc_frag() where possible Sebastian Andrzej Siewior
  2019-06-07 19:20 ` [PATCH v2 net-next 1/7] net: Don't disable interrupts in napi_alloc_frag() Sebastian Andrzej Siewior
  2019-06-07 19:20 ` [PATCH v2 net-next 2/7] net: Don't disable interrupts in __netdev_alloc_skb() Sebastian Andrzej Siewior
@ 2019-06-07 19:20 ` Sebastian Andrzej Siewior
  2019-06-07 19:20 ` [PATCH v2 net-next 4/7] dpaa2-eth: Use napi_alloc_frag() Sebastian Andrzej Siewior
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sebastian Andrzej Siewior @ 2019-06-07 19:20 UTC (permalink / raw)
  To: netdev; +Cc: tglx, David S. Miller, Sebastian Andrzej Siewior, Ioana Radulescu

According to the comment, the preempt_disable() statement is required
due to synchronisation in napi_alloc_frag(). The awful truth is that
local_bh_disable() is required because otherwise the NAPI poll callback
can be invoked while the open function setup buffers. This isn't
unlikely since the dpaa2 provides multiple devices.

The usage of napi_alloc_frag() has been removed in commit

 27c874867c4e9 ("dpaa2-eth: Use a single page per Rx buffer")

which means that the comment is not accurate and the preempt_disable()
statement is not required.

Remove the outdated comment and the no longer required
preempt_disable().

Cc: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Acked-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 7d2390e3df772..bcd3ceb5f9dc4 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -997,13 +997,6 @@ static int seed_pool(struct dpaa2_eth_priv *priv, u16 bpid)
 	int i, j;
 	int new_count;
 
-	/* This is the lazy seeding of Rx buffer pools.
-	 * dpaa2_add_bufs() is also used on the Rx hotpath and calls
-	 * napi_alloc_frag(). The trouble with that is that it in turn ends up
-	 * calling this_cpu_ptr(), which mandates execution in atomic context.
-	 * Rather than splitting up the code, do a one-off preempt disable.
-	 */
-	preempt_disable();
 	for (j = 0; j < priv->num_channels; j++) {
 		for (i = 0; i < DPAA2_ETH_NUM_BUFS;
 		     i += DPAA2_ETH_BUFS_PER_CMD) {
@@ -1011,12 +1004,10 @@ static int seed_pool(struct dpaa2_eth_priv *priv, u16 bpid)
 			priv->channel[j]->buf_count += new_count;
 
 			if (new_count < DPAA2_ETH_BUFS_PER_CMD) {
-				preempt_enable();
 				return -ENOMEM;
 			}
 		}
 	}
-	preempt_enable();
 
 	return 0;
 }
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 net-next 4/7] dpaa2-eth: Use napi_alloc_frag()
  2019-06-07 19:20 [PATCH v2 net-next 0/7] Avoid local_irq_save() and use napi_alloc_frag() where possible Sebastian Andrzej Siewior
                   ` (2 preceding siblings ...)
  2019-06-07 19:20 ` [PATCH v2 net-next 3/7] dpaa2-eth: Remove preempt_disable() from seed_pool() Sebastian Andrzej Siewior
@ 2019-06-07 19:20 ` Sebastian Andrzej Siewior
  2019-06-07 19:20 ` [PATCH v2 net-next 5/7] bnx2x: " Sebastian Andrzej Siewior
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sebastian Andrzej Siewior @ 2019-06-07 19:20 UTC (permalink / raw)
  To: netdev; +Cc: tglx, David S. Miller, Sebastian Andrzej Siewior, Ioana Radulescu

The driver is using netdev_alloc_frag() for allocation in the
->ndo_start_xmit() path. That one is always invoked in a BH disabled
region so we could also use napi_alloc_frag().

Use napi_alloc_frag() for skb allocation.

Cc: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Acked-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index bcd3ceb5f9dc4..becce4e89ea3b 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -555,7 +555,7 @@ static int build_sg_fd(struct dpaa2_eth_priv *priv,
 	/* Prepare the HW SGT structure */
 	sgt_buf_size = priv->tx_data_offset +
 		       sizeof(struct dpaa2_sg_entry) *  num_dma_bufs;
-	sgt_buf = netdev_alloc_frag(sgt_buf_size + DPAA2_ETH_TX_BUF_ALIGN);
+	sgt_buf = napi_alloc_frag(sgt_buf_size + DPAA2_ETH_TX_BUF_ALIGN);
 	if (unlikely(!sgt_buf)) {
 		err = -ENOMEM;
 		goto sgt_buf_alloc_failed;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 net-next 5/7] bnx2x: Use napi_alloc_frag()
  2019-06-07 19:20 [PATCH v2 net-next 0/7] Avoid local_irq_save() and use napi_alloc_frag() where possible Sebastian Andrzej Siewior
                   ` (3 preceding siblings ...)
  2019-06-07 19:20 ` [PATCH v2 net-next 4/7] dpaa2-eth: Use napi_alloc_frag() Sebastian Andrzej Siewior
@ 2019-06-07 19:20 ` Sebastian Andrzej Siewior
  2019-06-07 19:20 ` [PATCH v2 net-next 6/7] tg3: " Sebastian Andrzej Siewior
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sebastian Andrzej Siewior @ 2019-06-07 19:20 UTC (permalink / raw)
  To: netdev
  Cc: tglx, David S. Miller, Sebastian Andrzej Siewior, Ariel Elior,
	Sudarsana Kalluru, GR-everest-linux-l2

SKB allocation via bnx2x_frag_alloc() is always performed in NAPI
context. Preemptible context passes GFP_KERNEL and bnx2x_frag_alloc()
uses then __get_free_page() for the allocation.

Use napi_alloc_frag() for memory allocation.

Cc: Ariel Elior <aelior@marvell.com>
Cc: Sudarsana Kalluru <skalluru@marvell.com>
Cc: GR-everest-linux-l2@marvell.com
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 008ad0ca89ba0..c4986b5191916 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -684,7 +684,7 @@ static void *bnx2x_frag_alloc(const struct bnx2x_fastpath *fp, gfp_t gfp_mask)
 		if (unlikely(gfpflags_allow_blocking(gfp_mask)))
 			return (void *)__get_free_page(gfp_mask);
 
-		return netdev_alloc_frag(fp->rx_frag_size);
+		return napi_alloc_frag(fp->rx_frag_size);
 	}
 
 	return kmalloc(fp->rx_buf_size + NET_SKB_PAD, gfp_mask);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 net-next 6/7] tg3: Use napi_alloc_frag()
  2019-06-07 19:20 [PATCH v2 net-next 0/7] Avoid local_irq_save() and use napi_alloc_frag() where possible Sebastian Andrzej Siewior
                   ` (4 preceding siblings ...)
  2019-06-07 19:20 ` [PATCH v2 net-next 5/7] bnx2x: " Sebastian Andrzej Siewior
@ 2019-06-07 19:20 ` Sebastian Andrzej Siewior
  2019-06-07 19:20 ` [PATCH v2 net-next 7/7] net: hwbm: Make the hwbm_pool lock a mutex Sebastian Andrzej Siewior
  2019-06-10  2:40 ` [PATCH v2 net-next 0/7] Avoid local_irq_save() and use napi_alloc_frag() where possible David Miller
  7 siblings, 0 replies; 9+ messages in thread
From: Sebastian Andrzej Siewior @ 2019-06-07 19:20 UTC (permalink / raw)
  To: netdev
  Cc: tglx, David S. Miller, Sebastian Andrzej Siewior,
	Siva Reddy Kallam, Prashant Sreedharan, Michael Chan

tg3_alloc_rx_data() uses netdev_alloc_frag() for skb allocation. All
callers of tg3_alloc_rx_data() either hold tp->lock (which is held with
BH disabled) or run in NAPI context.

Use napi_alloc_frag() for skb allocations.

Cc: Siva Reddy Kallam <siva.kallam@broadcom.com>
Cc: Prashant Sreedharan <prashant@broadcom.com>
Cc: Michael Chan <mchan@broadcom.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/net/ethernet/broadcom/tg3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 6d1f9c822548e..4c404d2213f98 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -6710,7 +6710,7 @@ static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
 	skb_size = SKB_DATA_ALIGN(data_size + TG3_RX_OFFSET(tp)) +
 		   SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 	if (skb_size <= PAGE_SIZE) {
-		data = netdev_alloc_frag(skb_size);
+		data = napi_alloc_frag(skb_size);
 		*frag_size = skb_size;
 	} else {
 		data = kmalloc(skb_size, GFP_ATOMIC);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 net-next 7/7] net: hwbm: Make the hwbm_pool lock a mutex
  2019-06-07 19:20 [PATCH v2 net-next 0/7] Avoid local_irq_save() and use napi_alloc_frag() where possible Sebastian Andrzej Siewior
                   ` (5 preceding siblings ...)
  2019-06-07 19:20 ` [PATCH v2 net-next 6/7] tg3: " Sebastian Andrzej Siewior
@ 2019-06-07 19:20 ` Sebastian Andrzej Siewior
  2019-06-10  2:40 ` [PATCH v2 net-next 0/7] Avoid local_irq_save() and use napi_alloc_frag() where possible David Miller
  7 siblings, 0 replies; 9+ messages in thread
From: Sebastian Andrzej Siewior @ 2019-06-07 19:20 UTC (permalink / raw)
  To: netdev; +Cc: tglx, David S. Miller, Sebastian Andrzej Siewior, Thomas Petazzoni

Based on review, `lock' is only acquired in hwbm_pool_add() which is
invoked via ->probe(), ->resume() and ->ndo_change_mtu(). Based on this
the lock can become a mutex and there is no need to disable interrupts
during the procedure.
Now that the lock is a mutex, hwbm_pool_add() no longer invokes
hwbm_pool_refill() in an atomic context so we can pass GFP_KERNEL to
hwbm_pool_refill() and remove the `gfp' argument from hwbm_pool_add().

Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/net/ethernet/marvell/mvneta.c    |  2 +-
 drivers/net/ethernet/marvell/mvneta_bm.c |  4 ++--
 include/net/hwbm.h                       |  6 +++---
 net/core/hwbm.c                          | 15 +++++++--------
 4 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 269bd73be1a0a..fb9b27983b5e7 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -1118,7 +1118,7 @@ static void mvneta_bm_update_mtu(struct mvneta_port *pp, int mtu)
 			SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(bm_pool->pkt_size));
 
 	/* Fill entire long pool */
-	num = hwbm_pool_add(hwbm_pool, hwbm_pool->size, GFP_ATOMIC);
+	num = hwbm_pool_add(hwbm_pool, hwbm_pool->size);
 	if (num != hwbm_pool->size) {
 		WARN(1, "pool %d: %d of %d allocated\n",
 		     bm_pool->id, num, hwbm_pool->size);
diff --git a/drivers/net/ethernet/marvell/mvneta_bm.c b/drivers/net/ethernet/marvell/mvneta_bm.c
index de468e1bdba9f..82ee2bcca6fd2 100644
--- a/drivers/net/ethernet/marvell/mvneta_bm.c
+++ b/drivers/net/ethernet/marvell/mvneta_bm.c
@@ -190,7 +190,7 @@ struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,
 			SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 		hwbm_pool->construct = mvneta_bm_construct;
 		hwbm_pool->priv = new_pool;
-		spin_lock_init(&hwbm_pool->lock);
+		mutex_init(&hwbm_pool->buf_lock);
 
 		/* Create new pool */
 		err = mvneta_bm_pool_create(priv, new_pool);
@@ -201,7 +201,7 @@ struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,
 		}
 
 		/* Allocate buffers for this pool */
-		num = hwbm_pool_add(hwbm_pool, hwbm_pool->size, GFP_ATOMIC);
+		num = hwbm_pool_add(hwbm_pool, hwbm_pool->size);
 		if (num != hwbm_pool->size) {
 			WARN(1, "pool %d: %d of %d allocated\n",
 			     new_pool->id, num, hwbm_pool->size);
diff --git a/include/net/hwbm.h b/include/net/hwbm.h
index 89085e2e2da5e..81643cf8a1c43 100644
--- a/include/net/hwbm.h
+++ b/include/net/hwbm.h
@@ -12,18 +12,18 @@ struct hwbm_pool {
 	/* constructor called during alocation */
 	int (*construct)(struct hwbm_pool *bm_pool, void *buf);
 	/* protect acces to the buffer counter*/
-	spinlock_t lock;
+	struct mutex buf_lock;
 	/* private data */
 	void *priv;
 };
 #ifdef CONFIG_HWBM
 void hwbm_buf_free(struct hwbm_pool *bm_pool, void *buf);
 int hwbm_pool_refill(struct hwbm_pool *bm_pool, gfp_t gfp);
-int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp);
+int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num);
 #else
 void hwbm_buf_free(struct hwbm_pool *bm_pool, void *buf) {}
 int hwbm_pool_refill(struct hwbm_pool *bm_pool, gfp_t gfp) { return 0; }
-int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp)
+int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num)
 { return 0; }
 #endif /* CONFIG_HWBM */
 #endif /* _HWBM_H */
diff --git a/net/core/hwbm.c b/net/core/hwbm.c
index fd822ca5a2457..ac1a66df9adc0 100644
--- a/net/core/hwbm.c
+++ b/net/core/hwbm.c
@@ -43,34 +43,33 @@ int hwbm_pool_refill(struct hwbm_pool *bm_pool, gfp_t gfp)
 }
 EXPORT_SYMBOL_GPL(hwbm_pool_refill);
 
-int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp)
+int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num)
 {
 	int err, i;
-	unsigned long flags;
 
-	spin_lock_irqsave(&bm_pool->lock, flags);
+	mutex_lock(&bm_pool->buf_lock);
 	if (bm_pool->buf_num == bm_pool->size) {
 		pr_warn("pool already filled\n");
-		spin_unlock_irqrestore(&bm_pool->lock, flags);
+		mutex_unlock(&bm_pool->buf_lock);
 		return bm_pool->buf_num;
 	}
 
 	if (buf_num + bm_pool->buf_num > bm_pool->size) {
 		pr_warn("cannot allocate %d buffers for pool\n",
 			buf_num);
-		spin_unlock_irqrestore(&bm_pool->lock, flags);
+		mutex_unlock(&bm_pool->buf_lock);
 		return 0;
 	}
 
 	if ((buf_num + bm_pool->buf_num) < bm_pool->buf_num) {
 		pr_warn("Adding %d buffers to the %d current buffers will overflow\n",
 			buf_num,  bm_pool->buf_num);
-		spin_unlock_irqrestore(&bm_pool->lock, flags);
+		mutex_unlock(&bm_pool->buf_lock);
 		return 0;
 	}
 
 	for (i = 0; i < buf_num; i++) {
-		err = hwbm_pool_refill(bm_pool, gfp);
+		err = hwbm_pool_refill(bm_pool, GFP_KERNEL);
 		if (err < 0)
 			break;
 	}
@@ -79,7 +78,7 @@ int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp)
 	bm_pool->buf_num += i;
 
 	pr_debug("hwpm pool: %d of %d buffers added\n", i, buf_num);
-	spin_unlock_irqrestore(&bm_pool->lock, flags);
+	mutex_unlock(&bm_pool->buf_lock);
 
 	return i;
 }
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 net-next 0/7] Avoid local_irq_save() and use napi_alloc_frag() where possible
  2019-06-07 19:20 [PATCH v2 net-next 0/7] Avoid local_irq_save() and use napi_alloc_frag() where possible Sebastian Andrzej Siewior
                   ` (6 preceding siblings ...)
  2019-06-07 19:20 ` [PATCH v2 net-next 7/7] net: hwbm: Make the hwbm_pool lock a mutex Sebastian Andrzej Siewior
@ 2019-06-10  2:40 ` David Miller
  7 siblings, 0 replies; 9+ messages in thread
From: David Miller @ 2019-06-10  2:40 UTC (permalink / raw)
  To: bigeasy; +Cc: netdev, tglx

From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Date: Fri,  7 Jun 2019 21:20:33 +0200

> The first two patches remove local_irq_save() around
> `netdev_alloc_cache' which does not work on -RT. Besides helping -RT it
> whould benefit the users of the function since they can avoid disabling
> interrupts and save a few cycles.
> The remaining patches are from a time when I tried to remove
> `netdev_alloc_cache' but then noticed that we still have non-NAPI
> drivers using netdev_alloc_skb() and I dropped that idea. Using
> napi_alloc_frag() over netdev_alloc_frag() would skip the not required
> local_bh_disable() around the allocation.
 ...

Series applied, thanks.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2019-06-10  2:40 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-07 19:20 [PATCH v2 net-next 0/7] Avoid local_irq_save() and use napi_alloc_frag() where possible Sebastian Andrzej Siewior
2019-06-07 19:20 ` [PATCH v2 net-next 1/7] net: Don't disable interrupts in napi_alloc_frag() Sebastian Andrzej Siewior
2019-06-07 19:20 ` [PATCH v2 net-next 2/7] net: Don't disable interrupts in __netdev_alloc_skb() Sebastian Andrzej Siewior
2019-06-07 19:20 ` [PATCH v2 net-next 3/7] dpaa2-eth: Remove preempt_disable() from seed_pool() Sebastian Andrzej Siewior
2019-06-07 19:20 ` [PATCH v2 net-next 4/7] dpaa2-eth: Use napi_alloc_frag() Sebastian Andrzej Siewior
2019-06-07 19:20 ` [PATCH v2 net-next 5/7] bnx2x: " Sebastian Andrzej Siewior
2019-06-07 19:20 ` [PATCH v2 net-next 6/7] tg3: " Sebastian Andrzej Siewior
2019-06-07 19:20 ` [PATCH v2 net-next 7/7] net: hwbm: Make the hwbm_pool lock a mutex Sebastian Andrzej Siewior
2019-06-10  2:40 ` [PATCH v2 net-next 0/7] Avoid local_irq_save() and use napi_alloc_frag() where possible David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.