Skip to content

Commit d4edea4

Browse files
committed
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley: "A set of three fixes for the ipr driver and one fairly major one for memory leaks in the mq path of SCSI" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: fix memory leak with scsi-mq ipr: Fix invalid array indexing for HRRQ ipr: Fix incorrect trace indexing ipr: Fix locking for unit attention handling
2 parents 30c7b56 + 0c958ec commit d4edea4

File tree

4 files changed

+23
-14
lines changed

4 files changed

+23
-14
lines changed

drivers/scsi/ipr.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -599,9 +599,10 @@ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd,
599599
{
600600
struct ipr_trace_entry *trace_entry;
601601
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
602+
unsigned int trace_index;
602603

603-
trace_entry = &ioa_cfg->trace[atomic_add_return
604-
(1, &ioa_cfg->trace_index)%IPR_NUM_TRACE_ENTRIES];
604+
trace_index = atomic_add_return(1, &ioa_cfg->trace_index) & IPR_TRACE_INDEX_MASK;
605+
trace_entry = &ioa_cfg->trace[trace_index];
605606
trace_entry->time = jiffies;
606607
trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0];
607608
trace_entry->type = type;
@@ -1051,10 +1052,15 @@ static void ipr_send_blocking_cmd(struct ipr_cmnd *ipr_cmd,
10511052

10521053
static int ipr_get_hrrq_index(struct ipr_ioa_cfg *ioa_cfg)
10531054
{
1055+
unsigned int hrrq;
1056+
10541057
if (ioa_cfg->hrrq_num == 1)
1055-
return 0;
1056-
else
1057-
return (atomic_add_return(1, &ioa_cfg->hrrq_index) % (ioa_cfg->hrrq_num - 1)) + 1;
1058+
hrrq = 0;
1059+
else {
1060+
hrrq = atomic_add_return(1, &ioa_cfg->hrrq_index);
1061+
hrrq = (hrrq % (ioa_cfg->hrrq_num - 1)) + 1;
1062+
}
1063+
return hrrq;
10581064
}
10591065

10601066
/**
@@ -6263,21 +6269,23 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd)
62636269
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
62646270
struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
62656271
u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
6266-
unsigned long hrrq_flags;
6272+
unsigned long lock_flags;
62676273

62686274
scsi_set_resid(scsi_cmd, be32_to_cpu(ipr_cmd->s.ioasa.hdr.residual_data_len));
62696275

62706276
if (likely(IPR_IOASC_SENSE_KEY(ioasc) == 0)) {
62716277
scsi_dma_unmap(scsi_cmd);
62726278

6273-
spin_lock_irqsave(ipr_cmd->hrrq->lock, hrrq_flags);
6279+
spin_lock_irqsave(ipr_cmd->hrrq->lock, lock_flags);
62746280
list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
62756281
scsi_cmd->scsi_done(scsi_cmd);
6276-
spin_unlock_irqrestore(ipr_cmd->hrrq->lock, hrrq_flags);
6282+
spin_unlock_irqrestore(ipr_cmd->hrrq->lock, lock_flags);
62776283
} else {
6278-
spin_lock_irqsave(ipr_cmd->hrrq->lock, hrrq_flags);
6284+
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
6285+
spin_lock(&ipr_cmd->hrrq->_lock);
62796286
ipr_erp_start(ioa_cfg, ipr_cmd);
6280-
spin_unlock_irqrestore(ipr_cmd->hrrq->lock, hrrq_flags);
6287+
spin_unlock(&ipr_cmd->hrrq->_lock);
6288+
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
62816289
}
62826290
}
62836291

drivers/scsi/ipr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,6 +1486,7 @@ struct ipr_ioa_cfg {
14861486

14871487
#define IPR_NUM_TRACE_INDEX_BITS 8
14881488
#define IPR_NUM_TRACE_ENTRIES (1 << IPR_NUM_TRACE_INDEX_BITS)
1489+
#define IPR_TRACE_INDEX_MASK (IPR_NUM_TRACE_ENTRIES - 1)
14891490
#define IPR_TRACE_SIZE (sizeof(struct ipr_trace_entry) * IPR_NUM_TRACE_ENTRIES)
14901491
char trace_start[8];
14911492
#define IPR_TRACE_START_LABEL "trace"

drivers/scsi/scsi_error.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,7 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
944944
scmd->sdb.length);
945945
scmd->sdb.table.sgl = &ses->sense_sgl;
946946
scmd->sc_data_direction = DMA_FROM_DEVICE;
947-
scmd->sdb.table.nents = 1;
947+
scmd->sdb.table.nents = scmd->sdb.table.orig_nents = 1;
948948
scmd->cmnd[0] = REQUEST_SENSE;
949949
scmd->cmnd[4] = scmd->sdb.length;
950950
scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);

drivers/scsi/scsi_lib.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ static struct scatterlist *scsi_sg_alloc(unsigned int nents, gfp_t gfp_mask)
583583

584584
static void scsi_free_sgtable(struct scsi_data_buffer *sdb, bool mq)
585585
{
586-
if (mq && sdb->table.nents <= SCSI_MAX_SG_SEGMENTS)
586+
if (mq && sdb->table.orig_nents <= SCSI_MAX_SG_SEGMENTS)
587587
return;
588588
__sg_free_table(&sdb->table, SCSI_MAX_SG_SEGMENTS, mq, scsi_sg_free);
589589
}
@@ -597,8 +597,8 @@ static int scsi_alloc_sgtable(struct scsi_data_buffer *sdb, int nents, bool mq)
597597

598598
if (mq) {
599599
if (nents <= SCSI_MAX_SG_SEGMENTS) {
600-
sdb->table.nents = nents;
601-
sg_init_table(sdb->table.sgl, sdb->table.nents);
600+
sdb->table.nents = sdb->table.orig_nents = nents;
601+
sg_init_table(sdb->table.sgl, nents);
602602
return 0;
603603
}
604604
first_chunk = sdb->table.sgl;

0 commit comments

Comments
 (0)