Skip to content
  • Sebastian Andrzej Siewior's avatar
    0583531b
    RDMA/iser: Remove in_interrupt() usage · 0583531b
    Sebastian Andrzej Siewior authored
    iser_initialize_task_headers() uses in_interrupt() to find out if it is
    safe to acquire a mutex.
    
    in_interrupt() is deprecated as it is ill defined and does not provide
    what it suggests. Aside of that it covers only parts of the contexts in
    which a mutex may not be acquired.
    
    The following callchains exist:
    
    iscsi_queuecommand() *locks* iscsi_session::frwd_lock
    -> iscsi_prep_scsi_cmd_pdu()
       -> session->tt->init_task() (iscsi_iser_task_init())
          -> iser_initialize_task_headers()
    -> iscsi_iser_task_xmit() (iscsi_transport::xmit_task)
      -> iscsi_iser_task_xmit_unsol_data()
        -> iser_send_data_out()
          -> iser_initialize_task_headers()
    
    iscsi_data_xmit() *locks* iscsi_session::frwd_lock
    -> iscsi_prep_mgmt_task()
       -> session->tt->init_task() (iscsi_iser_task_init())
          -> iser_initialize_task_headers()
    -> iscsi_prep_scsi_cmd_pdu()
       -> session->tt->init_task() (iscsi_iser_task_init())
          -> iser_initialize_task_headers()
    
    __iscsi_conn_send_pdu() caller has iscsi_session::frwd_lock
      -> iscsi_prep_mgmt_task()
         -> session->tt->init_task() (iscsi_iser_task_init())
            -> iser_initialize_task_headers()
      -> session->tt->xmit_task() (
    
    The only callchain that is close to be invoked in preemptible context:
    iscsi_xmitworker() worker
    -> iscsi_data_xmit()
       -> iscsi_xmit_task()
          -> conn->session->tt->xmit_task() (iscsi_iser_task_xmit()
    
    In iscsi_iser_task_xmit() there is this check:
       if (!task->sc)
          return iscsi_iser_mtask_xmit(conn, task);
    
    so it does end up in iser_initialize_task_headers() and
    iser_initialize_task_headers() relies on iscsi_task::sc == NULL.
    
    Remove conditional locking of iser_conn::state_mutex because there is no
    call chain to do so. Remove the goto label and return early now that there
    is no clean up needed.
    
    Link: https://lore.kernel.org/r/20201204174256.62xfcvudndt7oufl@linutronix.de
    
    
    Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
    Cc: Sagi Grimberg <sagi@grimberg.me>
    Cc: Max Gurtovoy <maxg@nvidia.com>
    Cc: Doug Ledford <dledford@redhat.com>
    Cc: Jason Gunthorpe <jgg@ziepe.ca>
    Cc: linux-rdma@vger.kernel.org
    Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
    0583531b
    RDMA/iser: Remove in_interrupt() usage
    Sebastian Andrzej Siewior authored
    iser_initialize_task_headers() uses in_interrupt() to find out if it is
    safe to acquire a mutex.
    
    in_interrupt() is deprecated as it is ill defined and does not provide
    what it suggests. Aside of that it covers only parts of the contexts in
    which a mutex may not be acquired.
    
    The following callchains exist:
    
    iscsi_queuecommand() *locks* iscsi_session::frwd_lock
    -> iscsi_prep_scsi_cmd_pdu()
       -> session->tt->init_task() (iscsi_iser_task_init())
          -> iser_initialize_task_headers()
    -> iscsi_iser_task_xmit() (iscsi_transport::xmit_task)
      -> iscsi_iser_task_xmit_unsol_data()
        -> iser_send_data_out()
          -> iser_initialize_task_headers()
    
    iscsi_data_xmit() *locks* iscsi_session::frwd_lock
    -> iscsi_prep_mgmt_task()
       -> session->tt->init_task() (iscsi_iser_task_init())
          -> iser_initialize_task_headers()
    -> iscsi_prep_scsi_cmd_pdu()
       -> session->tt->init_task() (iscsi_iser_task_init())
          -> iser_initialize_task_headers()
    
    __iscsi_conn_send_pdu() caller has iscsi_session::frwd_lock
      -> iscsi_prep_mgmt_task()
         -> session->tt->init_task() (iscsi_iser_task_init())
            -> iser_initialize_task_headers()
      -> session->tt->xmit_task() (
    
    The only callchain that is close to be invoked in preemptible context:
    iscsi_xmitworker() worker
    -> iscsi_data_xmit()
       -> iscsi_xmit_task()
          -> conn->session->tt->xmit_task() (iscsi_iser_task_xmit()
    
    In iscsi_iser_task_xmit() there is this check:
       if (!task->sc)
          return iscsi_iser_mtask_xmit(conn, task);
    
    so it does end up in iser_initialize_task_headers() and
    iser_initialize_task_headers() relies on iscsi_task::sc == NULL.
    
    Remove conditional locking of iser_conn::state_mutex because there is no
    call chain to do so. Remove the goto label and return early now that there
    is no clean up needed.
    
    Link: https://lore.kernel.org/r/20201204174256.62xfcvudndt7oufl@linutronix.de
    
    
    Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
    Cc: Sagi Grimberg <sagi@grimberg.me>
    Cc: Max Gurtovoy <maxg@nvidia.com>
    Cc: Doug Ledford <dledford@redhat.com>
    Cc: Jason Gunthorpe <jgg@ziepe.ca>
    Cc: linux-rdma@vger.kernel.org
    Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Loading