On 11/21/22 8:17 AM, Wenchao Hao wrote: > And the function looks like following after change: > > static void __iscsi_unbind_session(struct work_struct *work) > { > struct iscsi_cls_session *session = > container_of(work, struct iscsi_cls_session, > unbind_work); > struct Scsi_Host *shost = iscsi_session_to_shost(session); > struct iscsi_cls_host *ihost = shost->shost_data; > unsigned long flags; > unsigned int target_id; > > ISCSI_DBG_TRANS_SESSION(session, "Unbinding session\n"); > > /* Prevent new scans and make sure scanning is not in progress */ > mutex_lock(&ihost->mutex); > spin_lock_irqsave(&session->lock, flags); > if (session->target_state != ISCSI_SESSION_TARGET_SCANNED) { What was the reason for not checking for ALLOCATED and freeing the ida in that case? > spin_unlock_irqrestore(&session->lock, flags); > mutex_unlock(&ihost->mutex); > ISCSI_DBG_TRANS_SESSION(session, "Skipping target unbinding: Session is %s.\n", > iscsi_session_target_state_name[session->target_state]); > return; > } > target_id = session->target_id; > session->target_id = ISCSI_MAX_TARGET; > session->target_state = ISCSI_SESSION_TARGET_UNBINDING; > spin_unlock_irqrestore(&session->lock, flags); > mutex_unlock(&ihost->mutex); > > scsi_remove_target(&session->dev); > > spin_lock_irqsave(&session->lock, flags); > session->target_state = ISCSI_SESSION_TARGET_UNBOUND; > spin_unlock_irqrestore(&session->lock, flags); > > if (session->ida_used) > ida_free(&iscsi_sess_ida, target_id); > > iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION); > ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n"); > } > > >