Hello Corey Minyard,

The patch 259307074bfc: "ipmi: Add SMBus interface driver (SSIF)"
from Mar 19, 2012, leads to the following static checker warning:

        drivers/char/ipmi/ipmi_ssif.c:841 msg_done_handler()
        error: double lock 'ssif_info->lock'

drivers/char/ipmi/ipmi_ssif.c
   733  
   734          flags = ipmi_ssif_lock_cond(ssif_info, &oflags);

We take the lock here.

   735          msg = ssif_info->curr_msg;
   736          if (msg) {
   737                  msg->rsp_size = len;
   738                  if (msg->rsp_size > IPMI_MAX_MSG_LENGTH)
   739                          msg->rsp_size = IPMI_MAX_MSG_LENGTH;
   740                  memcpy(msg->rsp, data, msg->rsp_size);
   741                  ssif_info->curr_msg = NULL;
   742          }
   743  
   744          switch (ssif_info->ssif_state) {
   745          case SSIF_NORMAL:
   746                  ipmi_ssif_unlock_cond(ssif_info, flags);
   747                  if (!msg)
   748                          break;
   749  
   750                  if (result < 0)
   751                          return_hosed_msg(ssif_info, msg);
   752                  else
   753                          deliver_recv_msg(ssif_info, msg);
   754                  break;
   755  
   756          case SSIF_GETTING_FLAGS:
   757                  /* We got the flags from the SSIF, now handle them. */
   758                  if ((result < 0) || (len < 4) || (data[2] != 0)) {
   759                          /*
   760                           * Error fetching flags, or invalid length,
   761                           * just give up for now.
   762                           */
   763                          ssif_info->ssif_state = SSIF_NORMAL;
   764                          ipmi_ssif_unlock_cond(ssif_info, flags);
   765                          pr_warn(PFX "Error getting flags: %d %d, %x\n",
   766                                 result, len, data[2]);
   767                  } else if (data[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2
   768                             || data[1] != IPMI_GET_MSG_FLAGS_CMD) {
   769                          pr_warn(PFX "Invalid response getting flags: %x 
%x\n",
   770                                  data[0], data[1]);

We don't unlock on this path...  The static checker is going to complain
anyway because there is no default case but that seems like a false
positive.

   771                  } else {
   772                          ssif_inc_stat(ssif_info, flag_fetches);
   773                          ssif_info->msg_flags = data[3];
   774                          handle_flags(ssif_info, flags);
   775                  }
   776                  break;
   777  
   778          case SSIF_CLEARING_FLAGS:
   779                  /* We cleared the flags. */
   780                  if ((result < 0) || (len < 3) || (data[2] != 0)) {
   781                          /* Error clearing flags */
   782                          pr_warn(PFX "Error clearing flags: %d %d, %x\n",
   783                                 result, len, data[2]);
   784                  } else if (data[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2
   785                             || data[1] != IPMI_CLEAR_MSG_FLAGS_CMD) {
   786                          pr_warn(PFX "Invalid response clearing flags: 
%x %x\n",
   787                                  data[0], data[1]);
   788                  }
   789                  ssif_info->ssif_state = SSIF_NORMAL;
   790                  ipmi_ssif_unlock_cond(ssif_info, flags);
   791                  break;
   792  
   793          case SSIF_GETTING_EVENTS:
   794                  if ((result < 0) || (len < 3) || (msg->rsp[2] != 0)) {
   795                          /* Error getting event, probably done. */
   796                          msg->done(msg);
   797  
   798                          /* Take off the event flag. */
   799                          ssif_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL;
   800                          handle_flags(ssif_info, flags);
   801                  } else if (msg->rsp[0] != (IPMI_NETFN_APP_REQUEST | 1) 
<< 2
   802                             || msg->rsp[1] != 
IPMI_READ_EVENT_MSG_BUFFER_CMD) {
   803                          pr_warn(PFX "Invalid response getting events: 
%x %x\n",
   804                                  msg->rsp[0], msg->rsp[1]);
   805                          msg->done(msg);
   806                          /* Take off the event flag. */
   807                          ssif_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL;
   808                          handle_flags(ssif_info, flags);
   809                  } else {
   810                          handle_flags(ssif_info, flags);
   811                          ssif_inc_stat(ssif_info, events);
   812                          deliver_recv_msg(ssif_info, msg);
   813                  }
   814                  break;
   815  
   816          case SSIF_GETTING_MESSAGES:
   817                  if ((result < 0) || (len < 3) || (msg->rsp[2] != 0)) {
   818                          /* Error getting event, probably done. */
   819                          msg->done(msg);
   820  
   821                          /* Take off the msg flag. */
   822                          ssif_info->msg_flags &= ~RECEIVE_MSG_AVAIL;
   823                          handle_flags(ssif_info, flags);
   824                  } else if (msg->rsp[0] != (IPMI_NETFN_APP_REQUEST | 1) 
<< 2
   825                             || msg->rsp[1] != IPMI_GET_MSG_CMD) {
   826                          pr_warn(PFX "Invalid response clearing flags: 
%x %x\n",
   827                                  msg->rsp[0], msg->rsp[1]);
   828                          msg->done(msg);
   829  
   830                          /* Take off the msg flag. */
   831                          ssif_info->msg_flags &= ~RECEIVE_MSG_AVAIL;
   832                          handle_flags(ssif_info, flags);
   833                  } else {
   834                          ssif_inc_stat(ssif_info, incoming_messages);
   835                          handle_flags(ssif_info, flags);
   836                          deliver_recv_msg(ssif_info, msg);
   837                  }
   838                  break;
   839          }
   840  
   841          flags = ipmi_ssif_lock_cond(ssif_info, &oflags);
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Deadlock.

   842          if (SSIF_IDLE(ssif_info) && !ssif_info->stopping) {
   843                  if (ssif_info->req_events)



regards,
dan carpenter

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Openipmi-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openipmi-developer

Reply via email to