Re: [bug report] net/smc: fix ref_tracker issue in smc_pnet_add()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Feb 7, 2022 at 11:15 PM Dan Carpenter <dan.carpenter@xxxxxxxxxx> wrote:
>
> Hello Eric Dumazet,
>
> The patch 28f922213886: "net/smc: fix ref_tracker issue in
> smc_pnet_add()" from Feb 5, 2022, leads to the following Smatch
> static checker warning:
>
>         net/smc/smc_pnet.c:384 smc_pnet_add_eth()
>         warn: sleeping in atomic context
>
> net/smc/smc_pnet.c
>     342 static int smc_pnet_add_eth(struct smc_pnettable *pnettable, struct net *net,
>     343                             char *eth_name, char *pnet_name)
>     344 {
>     345         struct smc_pnetentry *tmp_pe, *new_pe;
>     346         struct net_device *ndev, *base_ndev;
>     347         u8 ndev_pnetid[SMC_MAX_PNETID_LEN];
>     348         bool new_netdev;
>     349         int rc;
>     350
>     351         /* check if (base) netdev already has a pnetid. If there is one, we do
>     352          * not want to add a pnet table entry
>     353          */
>     354         rc = -EEXIST;
>     355         ndev = dev_get_by_name(net, eth_name);        /* dev_hold() */
>     356         if (ndev) {
>     357                 base_ndev = pnet_find_base_ndev(ndev);
>     358                 if (!smc_pnetid_by_dev_port(base_ndev->dev.parent,
>     359                                             base_ndev->dev_port, ndev_pnetid))
>     360                         goto out_put;
>     361         }
>     362
>     363         /* add a new netdev entry to the pnet table if there isn't one */
>     364         rc = -ENOMEM;
>     365         new_pe = kzalloc(sizeof(*new_pe), GFP_KERNEL);
>     366         if (!new_pe)
>     367                 goto out_put;
>     368         new_pe->type = SMC_PNET_ETH;
>     369         memcpy(new_pe->pnet_name, pnet_name, SMC_MAX_PNETID_LEN);
>     370         strncpy(new_pe->eth_name, eth_name, IFNAMSIZ);
>     371         rc = -EEXIST;
>     372         new_netdev = true;
>     373         write_lock(&pnettable->lock);
>     374         list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) {
>     375                 if (tmp_pe->type == SMC_PNET_ETH &&
>     376                     !strncmp(tmp_pe->eth_name, eth_name, IFNAMSIZ)) {
>     377                         new_netdev = false;
>     378                         break;
>     379                 }
>     380         }
>     381         if (new_netdev) {
>     382                 if (ndev) {
>     383                         new_pe->ndev = ndev;
> --> 384                         netdev_tracker_alloc(ndev, &new_pe->dev_tracker,
>     385                                              GFP_KERNEL);
>
> We can't do a GFP_KERNEL allocation here
>
>     386                 }
>     387                 list_add_tail(&new_pe->list, &pnettable->pnetlist);
>     388                 write_unlock(&pnettable->lock);
>
> because we're holding this write lock
>

Sure, the fix is already in net tree, and should reach your tree eventually.

Thanks.

commit 94fdd7c02a56d0316d20e417a1141b71a8dcee82 (HEAD -> net-1, net/master)
Author: Eric Dumazet <edumazet@xxxxxxxxxx>
Date:   Sun Feb 6 06:33:48 2022 -0800

    net/smc: use GFP_ATOMIC allocation in smc_pnet_add_eth()

    My last patch moved the netdev_tracker_alloc() call to a section
    protected by a write_lock().

    I should have replaced GFP_KERNEL with GFP_ATOMIC to avoid the infamous:

    BUG: sleeping function called from invalid context at
include/linux/sched/mm.h:256

    Fixes: 28f922213886 ("net/smc: fix ref_tracker issue in smc_pnet_add()")
    Signed-off-by: Eric Dumazet <edumazet@xxxxxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>

diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c
index fb6331d97185a5db9b4539e7f081e9fa469bc44b..0599246c037690b4b01813956e4af74519277bea
100644
--- a/net/smc/smc_pnet.c
+++ b/net/smc/smc_pnet.c
@@ -382,7 +382,7 @@ static int smc_pnet_add_eth(struct smc_pnettable
*pnettable, struct net *net,
                if (ndev) {
                        new_pe->ndev = ndev;
                        netdev_tracker_alloc(ndev, &new_pe->dev_tracker,
-                                            GFP_KERNEL);
+                                            GFP_ATOMIC);
                }
                list_add_tail(&new_pe->list, &pnettable->pnetlist);
                write_unlock(&pnettable->lock);



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Kernel Development]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Info]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Linux Media]     [Device Mapper]

  Powered by Linux