Skip to content

Commit 5565ec4

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: "Six small fixes. Four in drivers and the two core changes should be read together as a correction to a prior iorequest_cnt fix that exposed us to a potential use after free" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: core: Decrease scsi_device's iorequest_cnt if dispatch failed scsi: Revert "scsi: core: Do not increase scsi_device's iorequest_cnt if dispatch failed" scsi: storvsc: Don't pass unused PFNs to Hyper-V host scsi: ufs: core: Fix MCQ nr_hw_queues scsi: ufs: core: Rename symbol sizeof_utp_transfer_cmd_desc() scsi: ufs: core: Fix MCQ tag calculation
2 parents a594874 + 09e797c commit 5565ec4

File tree

5 files changed

+17
-13
lines changed

5 files changed

+17
-13
lines changed

drivers/scsi/scsi_lib.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1463,6 +1463,8 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
14631463
struct Scsi_Host *host = cmd->device->host;
14641464
int rtn = 0;
14651465

1466+
atomic_inc(&cmd->device->iorequest_cnt);
1467+
14661468
/* check if the device is still usable */
14671469
if (unlikely(cmd->device->sdev_state == SDEV_DEL)) {
14681470
/* in SDEV_DEL we error all commands. DID_NO_CONNECT
@@ -1483,6 +1485,7 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
14831485
*/
14841486
SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
14851487
"queuecommand : device blocked\n"));
1488+
atomic_dec(&cmd->device->iorequest_cnt);
14861489
return SCSI_MLQUEUE_DEVICE_BUSY;
14871490
}
14881491

@@ -1515,6 +1518,7 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
15151518
trace_scsi_dispatch_cmd_start(cmd);
15161519
rtn = host->hostt->queuecommand(host, cmd);
15171520
if (rtn) {
1521+
atomic_dec(&cmd->device->iorequest_cnt);
15181522
trace_scsi_dispatch_cmd_error(cmd, rtn);
15191523
if (rtn != SCSI_MLQUEUE_DEVICE_BUSY &&
15201524
rtn != SCSI_MLQUEUE_TARGET_BUSY)
@@ -1761,7 +1765,6 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
17611765
goto out_dec_host_busy;
17621766
}
17631767

1764-
atomic_inc(&cmd->device->iorequest_cnt);
17651768
return BLK_STS_OK;
17661769

17671770
out_dec_host_busy:

drivers/scsi/storvsc_drv.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,7 +1780,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
17801780

17811781
length = scsi_bufflen(scmnd);
17821782
payload = (struct vmbus_packet_mpb_array *)&cmd_request->mpb;
1783-
payload_sz = sizeof(cmd_request->mpb);
1783+
payload_sz = 0;
17841784

17851785
if (scsi_sg_count(scmnd)) {
17861786
unsigned long offset_in_hvpg = offset_in_hvpage(sgl->offset);
@@ -1789,10 +1789,10 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
17891789
unsigned long hvpfn, hvpfns_to_add;
17901790
int j, i = 0, sg_count;
17911791

1792-
if (hvpg_count > MAX_PAGE_BUFFER_COUNT) {
1792+
payload_sz = (hvpg_count * sizeof(u64) +
1793+
sizeof(struct vmbus_packet_mpb_array));
17931794

1794-
payload_sz = (hvpg_count * sizeof(u64) +
1795-
sizeof(struct vmbus_packet_mpb_array));
1795+
if (hvpg_count > MAX_PAGE_BUFFER_COUNT) {
17961796
payload = kzalloc(payload_sz, GFP_ATOMIC);
17971797
if (!payload)
17981798
return SCSI_MLQUEUE_DEVICE_BUSY;

drivers/ufs/core/ufs-mcq.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ static int ufshcd_mcq_config_nr_queues(struct ufs_hba *hba)
150150
u32 hba_maxq, rem, tot_queues;
151151
struct Scsi_Host *host = hba->host;
152152

153-
hba_maxq = FIELD_GET(MAX_QUEUE_SUP, hba->mcq_capabilities);
153+
/* maxq is 0 based value */
154+
hba_maxq = FIELD_GET(MAX_QUEUE_SUP, hba->mcq_capabilities) + 1;
154155

155156
tot_queues = UFS_MCQ_NUM_DEV_CMD_QUEUES + read_queues + poll_queues +
156157
rw_queues;
@@ -265,7 +266,7 @@ static int ufshcd_mcq_get_tag(struct ufs_hba *hba,
265266
addr = (le64_to_cpu(cqe->command_desc_base_addr) & CQE_UCD_BA) -
266267
hba->ucdl_dma_addr;
267268

268-
return div_u64(addr, sizeof(struct utp_transfer_cmd_desc));
269+
return div_u64(addr, ufshcd_get_ucd_size(hba));
269270
}
270271

271272
static void ufshcd_mcq_process_cqe(struct ufs_hba *hba,

drivers/ufs/core/ufshcd.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2849,10 +2849,10 @@ static void ufshcd_map_queues(struct Scsi_Host *shost)
28492849
static void ufshcd_init_lrb(struct ufs_hba *hba, struct ufshcd_lrb *lrb, int i)
28502850
{
28512851
struct utp_transfer_cmd_desc *cmd_descp = (void *)hba->ucdl_base_addr +
2852-
i * sizeof_utp_transfer_cmd_desc(hba);
2852+
i * ufshcd_get_ucd_size(hba);
28532853
struct utp_transfer_req_desc *utrdlp = hba->utrdl_base_addr;
28542854
dma_addr_t cmd_desc_element_addr = hba->ucdl_dma_addr +
2855-
i * sizeof_utp_transfer_cmd_desc(hba);
2855+
i * ufshcd_get_ucd_size(hba);
28562856
u16 response_offset = offsetof(struct utp_transfer_cmd_desc,
28572857
response_upiu);
28582858
u16 prdt_offset = offsetof(struct utp_transfer_cmd_desc, prd_table);
@@ -3761,7 +3761,7 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba)
37613761
size_t utmrdl_size, utrdl_size, ucdl_size;
37623762

37633763
/* Allocate memory for UTP command descriptors */
3764-
ucdl_size = sizeof_utp_transfer_cmd_desc(hba) * hba->nutrs;
3764+
ucdl_size = ufshcd_get_ucd_size(hba) * hba->nutrs;
37653765
hba->ucdl_base_addr = dmam_alloc_coherent(hba->dev,
37663766
ucdl_size,
37673767
&hba->ucdl_dma_addr,
@@ -3861,7 +3861,7 @@ static void ufshcd_host_memory_configure(struct ufs_hba *hba)
38613861
prdt_offset =
38623862
offsetof(struct utp_transfer_cmd_desc, prd_table);
38633863

3864-
cmd_desc_size = sizeof_utp_transfer_cmd_desc(hba);
3864+
cmd_desc_size = ufshcd_get_ucd_size(hba);
38653865
cmd_desc_dma_addr = hba->ucdl_dma_addr;
38663866

38673867
for (i = 0; i < hba->nutrs; i++) {
@@ -8452,7 +8452,7 @@ static void ufshcd_release_sdb_queue(struct ufs_hba *hba, int nutrs)
84528452
{
84538453
size_t ucdl_size, utrdl_size;
84548454

8455-
ucdl_size = sizeof(struct utp_transfer_cmd_desc) * nutrs;
8455+
ucdl_size = ufshcd_get_ucd_size(hba) * nutrs;
84568456
dmam_free_coherent(hba->dev, ucdl_size, hba->ucdl_base_addr,
84578457
hba->ucdl_dma_addr);
84588458

include/ufs/ufshcd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,7 @@ static inline size_t ufshcd_sg_entry_size(const struct ufs_hba *hba)
11331133
({ (void)(hba); BUILD_BUG_ON(sg_entry_size != sizeof(struct ufshcd_sg_entry)); })
11341134
#endif
11351135

1136-
static inline size_t sizeof_utp_transfer_cmd_desc(const struct ufs_hba *hba)
1136+
static inline size_t ufshcd_get_ucd_size(const struct ufs_hba *hba)
11371137
{
11381138
return sizeof(struct utp_transfer_cmd_desc) + SG_ALL * ufshcd_sg_entry_size(hba);
11391139
}

0 commit comments

Comments
 (0)