Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

scsi: pm8001: Fix tag values handling

The function pm8001_tag_alloc() determines free tags using the function
find_first_zero_bit() which can return 0 when the first bit of the bitmap
being inspected is 0. As such, tag 0 is a valid tag value that should not
be dismissed as invalid. Fix the functions pm8001_work_fn(),
mpi_sata_completion(), pm8001_mpi_task_abort_resp() and
pm8001_open_reject_retry() to not dismiss 0 tags as invalid.

The value 0xffffffff is used for invalid tags for unused ccb information
structures. Add the macro definition PM8001_INVALID_TAG to define this
value.

Link: https://lore.kernel.org/r/20220220031810.738362-20-damien.lemoal@opensource.wdc.com
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Damien Le Moal and committed by
Martin K. Petersen
7fb23a78 7e6b7e74

+28 -47
+18 -34
drivers/scsi/pm8001/pm8001_hwi.c
··· 1522 1522 case IO_XFER_ERROR_BREAK: 1523 1523 { /* This one stashes the sas_task instead */ 1524 1524 struct sas_task *t = (struct sas_task *)pm8001_dev; 1525 - u32 tag; 1526 1525 struct pm8001_ccb_info *ccb; 1527 1526 struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha; 1528 1527 unsigned long flags, flags1; ··· 1543 1544 /* Search for a possible ccb that matches the task */ 1544 1545 for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) { 1545 1546 ccb = &pm8001_ha->ccb_info[i]; 1546 - tag = ccb->ccb_tag; 1547 - if ((tag != 0xFFFFFFFF) && (ccb->task == t)) 1547 + if ((ccb->ccb_tag != PM8001_INVALID_TAG) && 1548 + (ccb->task == t)) 1548 1549 break; 1549 1550 } 1550 1551 if (!ccb) { ··· 1565 1566 spin_unlock_irqrestore(&t->task_state_lock, flags1); 1566 1567 pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with event 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n", 1567 1568 t, pw->handler, ts->resp, ts->stat); 1568 - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 1569 + pm8001_ccb_task_free(pm8001_ha, t, ccb, ccb->ccb_tag); 1569 1570 spin_unlock_irqrestore(&pm8001_ha->lock, flags); 1570 1571 } else { 1571 1572 spin_unlock_irqrestore(&t->task_state_lock, flags1); 1572 - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 1573 + pm8001_ccb_task_free(pm8001_ha, t, ccb, ccb->ccb_tag); 1573 1574 mb();/* in order to force CPU ordering */ 1574 1575 spin_unlock_irqrestore(&pm8001_ha->lock, flags); 1575 1576 t->task_done(t); ··· 1578 1579 case IO_XFER_OPEN_RETRY_TIMEOUT: 1579 1580 { /* This one stashes the sas_task instead */ 1580 1581 struct sas_task *t = (struct sas_task *)pm8001_dev; 1581 - u32 tag; 1582 1582 struct pm8001_ccb_info *ccb; 1583 1583 struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha; 1584 1584 unsigned long flags, flags1; ··· 1611 1613 /* Search for a possible ccb that matches the task */ 1612 1614 for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) { 1613 1615 ccb = &pm8001_ha->ccb_info[i]; 1614 - tag = ccb->ccb_tag; 1615 - if ((tag != 0xFFFFFFFF) && (ccb->task == t)) 1616 + if ((ccb->ccb_tag != PM8001_INVALID_TAG) && 1617 + (ccb->task == t)) 1616 1618 break; 1617 1619 } 1618 1620 if (!ccb) { ··· 1683 1685 struct task_status_struct *ts; 1684 1686 struct sas_task *task; 1685 1687 int i; 1686 - u32 tag, device_id; 1688 + u32 device_id; 1687 1689 1688 1690 for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) { 1689 1691 ccb = &pm8001_ha->ccb_info[i]; 1690 1692 task = ccb->task; 1691 1693 ts = &task->task_status; 1692 - tag = ccb->ccb_tag; 1693 - /* check if tag is NULL */ 1694 - if (!tag) { 1695 - pm8001_dbg(pm8001_ha, FAIL, 1696 - "tag Null\n"); 1697 - continue; 1698 - } 1694 + 1699 1695 if (task != NULL) { 1700 1696 dev = task->dev; 1701 1697 if (!dev) { ··· 1698 1706 continue; 1699 1707 } 1700 1708 /*complete sas task and update to top layer */ 1701 - pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); 1709 + pm8001_ccb_task_free(pm8001_ha, task, ccb, 1710 + ccb->ccb_tag); 1702 1711 ts->resp = SAS_TASK_COMPLETE; 1703 1712 task->task_done(task); 1704 - } else if (tag != 0xFFFFFFFF) { 1713 + } else if (ccb->ccb_tag != PM8001_INVALID_TAG) { 1705 1714 /* complete the internal commands/non-sas task */ 1706 1715 pm8001_dev = ccb->device; 1707 1716 if (pm8001_dev->dcompletion) { ··· 1710 1717 pm8001_dev->dcompletion = NULL; 1711 1718 } 1712 1719 complete(pm8001_ha->nvmd_completion); 1713 - pm8001_tag_free(pm8001_ha, tag); 1720 + pm8001_tag_free(pm8001_ha, ccb->ccb_tag); 1714 1721 } 1715 1722 } 1716 1723 /* Deregister all the device ids */ ··· 2305 2312 status = le32_to_cpu(psataPayload->status); 2306 2313 param = le32_to_cpu(psataPayload->param); 2307 2314 tag = le32_to_cpu(psataPayload->tag); 2308 - 2309 - if (!tag) { 2310 - pm8001_dbg(pm8001_ha, FAIL, "tag null\n"); 2311 - return; 2312 - } 2313 2315 2314 2316 ccb = &pm8001_ha->ccb_info[tag]; 2315 2317 t = ccb->task; ··· 3039 3051 device_id, pds, nds, status); 3040 3052 complete(pm8001_dev->setds_completion); 3041 3053 ccb->task = NULL; 3042 - ccb->ccb_tag = 0xFFFFFFFF; 3054 + ccb->ccb_tag = PM8001_INVALID_TAG; 3043 3055 pm8001_tag_free(pm8001_ha, tag); 3044 3056 } 3045 3057 ··· 3057 3069 dlen_status); 3058 3070 } 3059 3071 ccb->task = NULL; 3060 - ccb->ccb_tag = 0xFFFFFFFF; 3072 + ccb->ccb_tag = PM8001_INVALID_TAG; 3061 3073 pm8001_tag_free(pm8001_ha, tag); 3062 3074 } 3063 3075 ··· 3084 3096 * freed by requesting path anywhere. 3085 3097 */ 3086 3098 ccb->task = NULL; 3087 - ccb->ccb_tag = 0xFFFFFFFF; 3099 + ccb->ccb_tag = PM8001_INVALID_TAG; 3088 3100 pm8001_tag_free(pm8001_ha, tag); 3089 3101 return; 3090 3102 } ··· 3130 3142 complete(pm8001_ha->nvmd_completion); 3131 3143 pm8001_dbg(pm8001_ha, MSG, "Get nvmd data complete!\n"); 3132 3144 ccb->task = NULL; 3133 - ccb->ccb_tag = 0xFFFFFFFF; 3145 + ccb->ccb_tag = PM8001_INVALID_TAG; 3134 3146 pm8001_tag_free(pm8001_ha, tag); 3135 3147 } 3136 3148 ··· 3543 3555 } 3544 3556 complete(pm8001_dev->dcompletion); 3545 3557 ccb->task = NULL; 3546 - ccb->ccb_tag = 0xFFFFFFFF; 3558 + ccb->ccb_tag = PM8001_INVALID_TAG; 3547 3559 pm8001_tag_free(pm8001_ha, htag); 3548 3560 return 0; 3549 3561 } ··· 3615 3627 } 3616 3628 kfree(ccb->fw_control_context); 3617 3629 ccb->task = NULL; 3618 - ccb->ccb_tag = 0xFFFFFFFF; 3630 + ccb->ccb_tag = PM8001_INVALID_TAG; 3619 3631 pm8001_tag_free(pm8001_ha, tag); 3620 3632 complete(pm8001_ha->nvmd_completion); 3621 3633 return 0; ··· 3651 3663 3652 3664 status = le32_to_cpu(pPayload->status); 3653 3665 tag = le32_to_cpu(pPayload->tag); 3654 - if (!tag) { 3655 - pm8001_dbg(pm8001_ha, FAIL, " TAG NULL. RETURNING !!!\n"); 3656 - return -1; 3657 - } 3658 3666 3659 3667 scp = le32_to_cpu(pPayload->scp); 3660 3668 ccb = &pm8001_ha->ccb_info[tag];
+2 -1
drivers/scsi/pm8001/pm8001_init.c
··· 1217 1217 goto err_out; 1218 1218 } 1219 1219 pm8001_ha->ccb_info[i].task = NULL; 1220 - pm8001_ha->ccb_info[i].ccb_tag = 0xffffffff; 1220 + pm8001_ha->ccb_info[i].ccb_tag = PM8001_INVALID_TAG; 1221 1221 pm8001_ha->ccb_info[i].device = NULL; 1222 1222 ++pm8001_ha->tags_num; 1223 1223 } 1224 + 1224 1225 return 0; 1225 1226 1226 1227 err_out_noccb:
+6 -7
drivers/scsi/pm8001/pm8001_sas.c
··· 553 553 554 554 task->lldd_task = NULL; 555 555 ccb->task = NULL; 556 - ccb->ccb_tag = 0xFFFFFFFF; 556 + ccb->ccb_tag = PM8001_INVALID_TAG; 557 557 ccb->open_retry = 0; 558 558 pm8001_tag_free(pm8001_ha, ccb_idx); 559 559 } ··· 831 831 struct task_status_struct *ts; 832 832 struct pm8001_device *pm8001_dev; 833 833 unsigned long flags1; 834 - u32 tag; 835 834 struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[i]; 835 + 836 + if (ccb->ccb_tag == PM8001_INVALID_TAG) 837 + continue; 836 838 837 839 pm8001_dev = ccb->device; 838 840 if (!pm8001_dev || (pm8001_dev->dev_type == SAS_PHY_UNUSED)) ··· 846 844 || ((d / sizeof(*pm8001_dev)) >= PM8001_MAX_DEVICES)) 847 845 continue; 848 846 } else if (pm8001_dev != device_to_close) 849 - continue; 850 - tag = ccb->ccb_tag; 851 - if (!tag || (tag == 0xFFFFFFFF)) 852 847 continue; 853 848 task = ccb->task; 854 849 if (!task || !task->task_done) ··· 866 867 & SAS_TASK_STATE_ABORTED))) { 867 868 spin_unlock_irqrestore(&task->task_state_lock, 868 869 flags1); 869 - pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); 870 + pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb->ccb_tag); 870 871 } else { 871 872 spin_unlock_irqrestore(&task->task_state_lock, 872 873 flags1); 873 - pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); 874 + pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb->ccb_tag); 874 875 mb();/* in order to force CPU ordering */ 875 876 spin_unlock_irqrestore(&pm8001_ha->lock, flags); 876 877 task->task_done(task);
+2
drivers/scsi/pm8001/pm8001_sas.h
··· 732 732 /* ctl shared API */ 733 733 extern const struct attribute_group *pm8001_host_groups[]; 734 734 735 + #define PM8001_INVALID_TAG ((u32)-1) 736 + 735 737 static inline void 736 738 pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha, 737 739 struct sas_task *task, struct pm8001_ccb_info *ccb,
-5
drivers/scsi/pm8001/pm80xx_hwi.c
··· 2402 2402 param = le32_to_cpu(psataPayload->param); 2403 2403 tag = le32_to_cpu(psataPayload->tag); 2404 2404 2405 - if (!tag) { 2406 - pm8001_dbg(pm8001_ha, FAIL, "tag null\n"); 2407 - return; 2408 - } 2409 - 2410 2405 ccb = &pm8001_ha->ccb_info[tag]; 2411 2406 t = ccb->task; 2412 2407 pm8001_dev = ccb->device;