On Tue, Aug 19, 2025 at 10:53:47AM +0300, Dan Carpenter wrote:
> 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

Thanks, I have a fix in the next tree, I'll get it up to Linus after
letting it soak there a bit.

-corey

> 
> 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