[ Really old patch... :/ - dan ] Hello James Smart, The patch 92d7f7b0cde3: "[SCSI] lpfc: NPIV: add NPIV support on top of SLI-3" from Jun 17, 2007, leads to the following static checker warning: drivers/scsi/lpfc/lpfc_els.c:6148 lpfc_els_rcv_rscn() error: buffer underflow 'vport->fc_rscn_id_list' drivers/scsi/lpfc/lpfc_els.c 6128 /* Indicate we are walking fc_rscn_id_list on this vport */ 6129 vport->fc_rscn_flush = 1; 6130 spin_unlock_irq(shost->host_lock); 6131 /* Get the array count after successfully have the token */ 6132 rscn_cnt = vport->fc_rscn_id_cnt; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ We set rscn_cnt here. rscn_cnt is an int. Smatch thinks vport->fc_rscn_id_cnt can be higher than INT_MAX which is not actually possible but hopefully explains the warning message. More analysis below. 6133 /* If we are already processing an RSCN, save the received 6134 * RSCN payload buffer, cmdiocb->context2 to process later. 6135 */ 6136 if (vport->fc_flag & (FC_RSCN_MODE | FC_NDISC_ACTIVE)) { 6137 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, 6138 "RCV RSCN defer: did:x%x/ste:x%x flg:x%x", 6139 ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag); 6140 6141 spin_lock_irq(shost->host_lock); 6142 vport->fc_flag |= FC_RSCN_DEFERRED; 6143 if ((rscn_cnt < FC_MAX_HOLD_RSCN) && ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ On this path we check if it's invalid. 6144 !(vport->fc_flag & FC_RSCN_DISCOVERY)) { 6145 vport->fc_flag |= FC_RSCN_MODE; 6146 spin_unlock_irq(shost->host_lock); 6147 if (rscn_cnt) { 6148 cmd = vport->fc_rscn_id_list[rscn_cnt-1]->virt; 6149 length = be32_to_cpu(*cmd & ~ELS_CMD_MASK); 6150 } 6151 if ((rscn_cnt) && 6152 (payload_len + length <= LPFC_BPL_SIZE)) { 6153 *cmd &= ELS_CMD_MASK; 6154 *cmd |= cpu_to_be32(payload_len + length); 6155 memcpy(((uint8_t *)cmd) + length, lp, 6156 payload_len); 6157 } else { 6158 vport->fc_rscn_id_list[rscn_cnt] = pcmd; 6159 vport->fc_rscn_id_cnt++; ^^^^^^^^^^^^^^^^^^^^^^^ It gets incremented here 6160 /* If we zero, cmdiocb->context2, the calling 6161 * routine will not try to free it. 6162 */ 6163 cmdiocb->context2 = NULL; 6164 } 6165 /* Deferred RSCN */ 6166 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 6167 "0235 Deferred RSCN " 6168 "Data: x%x x%x x%x\n", 6169 vport->fc_rscn_id_cnt, vport->fc_flag, 6170 vport->port_state); 6171 } else { 6172 vport->fc_flag |= FC_RSCN_DISCOVERY; 6173 spin_unlock_irq(shost->host_lock); 6174 /* ReDiscovery RSCN */ 6175 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 6176 "0234 ReDiscovery RSCN " 6177 "Data: x%x x%x x%x\n", 6178 vport->fc_rscn_id_cnt, vport->fc_flag, 6179 vport->port_state); 6180 } 6181 /* Indicate we are done walking fc_rscn_id_list on this vport */ 6182 vport->fc_rscn_flush = 0; 6183 /* Send back ACC */ 6184 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); 6185 /* send RECOVERY event for ALL nodes that match RSCN payload */ 6186 lpfc_rscn_recovery_check(vport); 6187 spin_lock_irq(shost->host_lock); 6188 vport->fc_flag &= ~FC_RSCN_DEFERRED; 6189 spin_unlock_irq(shost->host_lock); 6190 return 0; 6191 } 6192 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, 6193 "RCV RSCN: did:x%x/ste:x%x flg:x%x", 6194 ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag); 6195 6196 spin_lock_irq(shost->host_lock); 6197 vport->fc_flag |= FC_RSCN_MODE; 6198 spin_unlock_irq(shost->host_lock); 6199 vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd; ^^^^^^^^^^^^^^^^^^^^^^^ But here we don't check here. It feels like we should be checking on this path as well. 6200 /* Indicate we are done walking fc_rscn_id_list on this vport */ 6201 vport->fc_rscn_flush = 0; regards, dan carpenter