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

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

 



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

    389         } else {
    390                 write_unlock(&pnettable->lock);
    391                 kfree(new_pe);
    392                 goto out_put;
    393         }
    394         if (ndev)
    395                 pr_warn_ratelimited("smc: net device %s "
    396                                     "applied user defined pnetid %.16s\n",
    397                                     new_pe->eth_name, new_pe->pnet_name);
    398         return 0;
    399 
    400 out_put:
    401         dev_put(ndev);
    402         return rc;
    403 }

regards,
dan carpenter



[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