Skip to content

Commit b5d1531

Browse files
Quinn Tranmartinkpetersen
authored andcommitted
scsi: qla2xxx: Fix slow mem alloc behind lock
Call Trace: [<ffffffff81341687>] dump_stack+0x6b/0xa4 [<ffffffff810c3e30>] ? print_irqtrace_events+0xd0/0xe0 [<ffffffff8109e3c3>] ___might_sleep+0x183/0x240 [<ffffffff8109e4d2>] __might_sleep+0x52/0x90 [<ffffffff811fe17b>] kmem_cache_alloc_trace+0x5b/0x300 [<ffffffff810c666b>] ? __lock_acquired+0x30b/0x420 [<ffffffffa0733c28>] qla2x00_alloc_fcport+0x38/0x2a0 [qla2xxx] [<ffffffffa07217f4>] ? qla2x00_do_work+0x34/0x2b0 [qla2xxx] [<ffffffff816cc82b>] ? _raw_spin_lock_irqsave+0x7b/0x90 [<ffffffffa072169a>] ? qla24xx_create_new_sess+0x3a/0x160 [qla2xxx] [<ffffffffa0721723>] qla24xx_create_new_sess+0xc3/0x160 [qla2xxx] [<ffffffff810c91ed>] ? trace_hardirqs_on+0xd/0x10 [<ffffffffa07218f8>] qla2x00_do_work+0x138/0x2b0 [qla2xxx] Signed-off-by: Quinn Tran <[email protected]> Signed-off-by: Himanshu Madhani <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 1a28faa commit b5d1531

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

drivers/scsi/qla2xxx/qla_gbl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ int qla24xx_post_gpdb_work(struct scsi_qla_host *, fc_port_t *, u8);
113113
extern char qla2x00_version_str[];
114114

115115
extern struct kmem_cache *srb_cachep;
116+
extern struct kmem_cache *qla_tgt_plogi_cachep;
116117

117118
extern int ql2xlogintimeout;
118119
extern int qlport_down_retry;

drivers/scsi/qla2xxx/qla_os.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4677,9 +4677,10 @@ static
46774677
void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
46784678
{
46794679
unsigned long flags;
4680-
fc_port_t *fcport = NULL;
4680+
fc_port_t *fcport = NULL, *tfcp;
46814681
struct qlt_plogi_ack_t *pla =
46824682
(struct qlt_plogi_ack_t *)e->u.new_sess.pla;
4683+
uint8_t free_fcport = 0;
46834684

46844685
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
46854686
fcport = qla2x00_find_fcport_by_wwpn(vha, e->u.new_sess.port_name, 1);
@@ -4694,6 +4695,7 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
46944695
pla->ref_count--;
46954696
}
46964697
} else {
4698+
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
46974699
fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
46984700
if (fcport) {
46994701
fcport->d_id = e->u.new_sess.id;
@@ -4703,6 +4705,29 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
47034705

47044706
memcpy(fcport->port_name, e->u.new_sess.port_name,
47054707
WWN_SIZE);
4708+
} else {
4709+
ql_dbg(ql_dbg_disc, vha, 0xffff,
4710+
"%s %8phC mem alloc fail.\n",
4711+
__func__, e->u.new_sess.port_name);
4712+
4713+
if (pla)
4714+
kmem_cache_free(qla_tgt_plogi_cachep, pla);
4715+
return;
4716+
}
4717+
4718+
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
4719+
/* search again to make sure one else got ahead */
4720+
tfcp = qla2x00_find_fcport_by_wwpn(vha,
4721+
e->u.new_sess.port_name, 1);
4722+
if (tfcp) {
4723+
/* should rarily happen */
4724+
ql_dbg(ql_dbg_disc, vha, 0xffff,
4725+
"%s %8phC found existing fcport b4 add. DS %d LS %d\n",
4726+
__func__, tfcp->port_name, tfcp->disc_state,
4727+
tfcp->fw_login_state);
4728+
4729+
free_fcport = 1;
4730+
} else {
47064731
list_add_tail(&fcport->list, &vha->vp_fcports);
47074732

47084733
if (pla) {
@@ -4720,6 +4745,12 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
47204745
else
47214746
qla24xx_async_gnl(vha, fcport);
47224747
}
4748+
4749+
if (free_fcport) {
4750+
qla2x00_free_fcport(fcport);
4751+
if (pla)
4752+
kmem_cache_free(qla_tgt_plogi_cachep, pla);
4753+
}
47234754
}
47244755

47254756
void

drivers/scsi/qla2xxx/qla_target.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ static void qlt_send_busy(struct qla_qpair *, struct atio_from_isp *,
145145
* Global Variables
146146
*/
147147
static struct kmem_cache *qla_tgt_mgmt_cmd_cachep;
148-
static struct kmem_cache *qla_tgt_plogi_cachep;
148+
struct kmem_cache *qla_tgt_plogi_cachep;
149149
static mempool_t *qla_tgt_mgmt_cmd_mempool;
150150
static struct workqueue_struct *qla_tgt_wq;
151151
static DEFINE_MUTEX(qla_tgt_mutex);

0 commit comments

Comments
 (0)