Hello Corey Minyard,

Commit 3be997d5a64a ("ipmi:msghandler: Remove srcu from the ipmi user
structure") from Mar 18, 2025 (linux-next), leads to the following
Smatch static checker warning:

        drivers/char/ipmi/ipmi_msghandler.c:5265 ipmi_free_recv_msg()
        warn: sleeping in atomic context

drivers/char/ipmi/ipmi_msghandler.c
    5262 void ipmi_free_recv_msg(struct ipmi_recv_msg *msg)
    5263 {
    5264         if (msg->user && !oops_in_progress)
--> 5265                 kref_put(&msg->user->refcount, free_ipmi_user);

The call to vfree() sleeps (unless you're in an IRQ handler).

    5266         msg->done(msg);
    5267 }

The problem is:
drivers/char/ipmi/ipmi_msghandler.c
  1331  static void _ipmi_destroy_user(struct ipmi_user *user)
  1332  {
  1333          struct ipmi_smi  *intf = user->intf;
  1334          int              i;
  1335          unsigned long    flags;
  1336          struct cmd_rcvr  *rcvr;
  1337          struct cmd_rcvr  *rcvrs = NULL;
  1338          struct ipmi_recv_msg *msg, *msg2;
  1339  
  1340          if (!refcount_dec_if_one(&user->destroyed))
  1341                  return;
  1342  
  1343          if (user->handler->shutdown)
  1344                  user->handler->shutdown(user->handler_data);
  1345  
  1346          if (user->handler->ipmi_watchdog_pretimeout)
  1347                  smi_remove_watch(intf, IPMI_WATCH_MASK_CHECK_WATCHDOG);
  1348  
  1349          if (user->gets_events)
  1350                  atomic_dec(&intf->event_waiters);
  1351  
  1352          /* Remove the user from the interface's list and sequence 
table. */
  1353          list_del(&user->link);
  1354          atomic_dec(&intf->nr_users);
  1355  
  1356          spin_lock_irqsave(&intf->seq_lock, flags);
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Holding a spinlock.

  1357          for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
  1358                  if (intf->seq_table[i].inuse
  1359                      && (intf->seq_table[i].recv_msg->user == user)) {
  1360                          intf->seq_table[i].inuse = 0;
  1361                          smi_remove_watch(intf, 
IPMI_WATCH_MASK_CHECK_MESSAGES);
  1362                          ipmi_free_recv_msg(intf->seq_table[i].recv_msg);
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Called here.

  1363                  }
  1364          }
  1365          spin_unlock_irqrestore(&intf->seq_lock, flags);

regards,
dan carpenter


_______________________________________________
Openipmi-developer mailing list
Openipmi-developer@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openipmi-developer

Reply via email to