net: hwbm: Make the hwbm_pool lock a mutex
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Fri, 7 Jun 2019 19:20:40 +0000 (21:20 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 10 Jun 2019 02:40:10 +0000 (19:40 -0700)
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>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/marvell/mvneta_bm.c
include/net/hwbm.h
net/core/hwbm.c

index 94dc0a2726448e6d80a2605dade35005ebb288b6..895bfed26a8a58b487280d85650f99cdb7fa5067 100644 (file)
@@ -1119,7 +1119,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);
index de468e1bdba9f3fb8bd66db9ee528b6859d7bf6c..82ee2bcca6fd2eb48c85d7966b593b61985a631e 100644 (file)
@@ -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);
index 89085e2e2da5e9d05662cc253758eedeab8c43b0..81643cf8a1c43ea5d7a61aba0722fd2c37e55f2c 100644 (file)
@@ -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 */
index fd822ca5a245754088d3d8d23fc1369e01f808a3..ac1a66df9adc03c4624604bb15dfbabdbe32c74c 100644 (file)
@@ -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;
 }