2020-08-17 08:55:20

by Allen Pais

[permalink] [raw]
Subject: [PATCH 0/8] scsi: convert tasklets to use new tasklet_setup()

From: Allen Pais <[email protected]>

Commit 12cc923f1ccc ("tasklet: Introduce new initialization API")'
introduced a new tasklet initialization API. This series converts
all the scsi drivers to use the new tasklet_setup() API

Allen Pais (8):
scsi: aic94xx: convert tasklets to use new tasklet_setup() API
scsi: esas2r: convert tasklets to use new tasklet_setup() API
scsi: ibmvscsi: convert tasklets to use new tasklet_setup() API
scsi: isci: convert tasklets to use new tasklet_setup() API
scsi: megaraid: convert tasklets to use new tasklet_setup() API
scsi: mvsas: convert tasklets to use new tasklet_setup() API
scsi: pm8001: convert tasklets to use new tasklet_setup() API
scsi: pmcraid: convert tasklets to use new tasklet_setup() API

drivers/scsi/aic94xx/aic94xx_hwi.c | 9 ++--
drivers/scsi/esas2r/esas2r.h | 2 +-
drivers/scsi/esas2r/esas2r_init.c | 4 +-
drivers/scsi/esas2r/esas2r_main.c | 4 +-
drivers/scsi/ibmvscsi/ibmvfc.c | 6 +--
drivers/scsi/ibmvscsi/ibmvscsi.c | 8 +--
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 7 ++-
drivers/scsi/isci/host.c | 4 +-
drivers/scsi/isci/host.h | 2 +-
drivers/scsi/isci/init.c | 3 +-
drivers/scsi/megaraid/megaraid_mbox.c | 9 ++--
drivers/scsi/megaraid/megaraid_sas.h | 2 +-
drivers/scsi/megaraid/megaraid_sas_base.c | 16 +++---
drivers/scsi/megaraid/megaraid_sas_fusion.c | 14 +++---
drivers/scsi/mvsas/mv_init.c | 8 +--
drivers/scsi/pm8001/pm8001_init.c | 55 ++++++++++++---------
drivers/scsi/pm8001/pm8001_sas.h | 6 ++-
drivers/scsi/pmcraid.c | 29 +++++------
drivers/scsi/pmcraid.h | 9 +++-
19 files changed, 104 insertions(+), 93 deletions(-)

--
2.17.1


2020-08-17 08:55:45

by Allen Pais

[permalink] [raw]
Subject: [PATCH 2/8] scsi: esas2r: convert tasklets to use new tasklet_setup() API

From: Allen Pais <[email protected]>

In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.

Signed-off-by: Romain Perier <[email protected]>
Signed-off-by: Allen Pais <[email protected]>
---
drivers/scsi/esas2r/esas2r.h | 2 +-
drivers/scsi/esas2r/esas2r_init.c | 4 +---
drivers/scsi/esas2r/esas2r_main.c | 4 ++--
3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/esas2r/esas2r.h b/drivers/scsi/esas2r/esas2r.h
index e30d2f1f5368..b99434e24868 100644
--- a/drivers/scsi/esas2r/esas2r.h
+++ b/drivers/scsi/esas2r/esas2r.h
@@ -992,7 +992,7 @@ int esas2r_write_vda(struct esas2r_adapter *a, const char *buf, long off,
int esas2r_read_fs(struct esas2r_adapter *a, char *buf, long off, int count);
int esas2r_write_fs(struct esas2r_adapter *a, const char *buf, long off,
int count);
-void esas2r_adapter_tasklet(unsigned long context);
+void esas2r_adapter_tasklet(struct tasklet_struct *t);
irqreturn_t esas2r_interrupt(int irq, void *dev_id);
irqreturn_t esas2r_msi_interrupt(int irq, void *dev_id);
void esas2r_kickoff_timer(struct esas2r_adapter *a);
diff --git a/drivers/scsi/esas2r/esas2r_init.c b/drivers/scsi/esas2r/esas2r_init.c
index eb7d139ffc00..55387c14fb8d 100644
--- a/drivers/scsi/esas2r/esas2r_init.c
+++ b/drivers/scsi/esas2r/esas2r_init.c
@@ -401,9 +401,7 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
return 0;
}

- tasklet_init(&a->tasklet,
- esas2r_adapter_tasklet,
- (unsigned long)a);
+ tasklet_setup(&a->tasklet, esas2r_adapter_tasklet);

/*
* Disable chip interrupts to prevent spurious interrupts
diff --git a/drivers/scsi/esas2r/esas2r_main.c b/drivers/scsi/esas2r/esas2r_main.c
index 7b49e2e9fcde..7ffa9406ab4d 100644
--- a/drivers/scsi/esas2r/esas2r_main.c
+++ b/drivers/scsi/esas2r/esas2r_main.c
@@ -1546,9 +1546,9 @@ void esas2r_complete_request_cb(struct esas2r_adapter *a,
}

/* Run tasklet to handle stuff outside of interrupt context. */
-void esas2r_adapter_tasklet(unsigned long context)
+void esas2r_adapter_tasklet(struct tasklet_struct *t)
{
- struct esas2r_adapter *a = (struct esas2r_adapter *)context;
+ struct esas2r_adapter *a = from_tasklet(a, t, tasklet);

if (unlikely(test_bit(AF2_TIMER_TICK, &a->flags2))) {
clear_bit(AF2_TIMER_TICK, &a->flags2);
--
2.17.1

2020-08-17 08:56:11

by Allen Pais

[permalink] [raw]
Subject: [PATCH 8/8] scsi: pmcraid: convert tasklets to use new tasklet_setup() API

From: Allen Pais <[email protected]>

In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.

Signed-off-by: Romain Perier <[email protected]>
Signed-off-by: Allen Pais <[email protected]>
---
drivers/scsi/pmcraid.c | 29 +++++++++++++++--------------
drivers/scsi/pmcraid.h | 9 +++++++--
2 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index aa9ae2ae8579..b7bbefcbb11d 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -4198,7 +4198,7 @@ static irqreturn_t pmcraid_isr_msix(int irq, void *dev_id)
}
}

- tasklet_schedule(&(pinstance->isr_tasklet[hrrq_id]));
+ tasklet_schedule(&(pinstance->isr_tasklet[hrrq_id]).tasklet);

return IRQ_HANDLED;
}
@@ -4267,7 +4267,7 @@ static irqreturn_t pmcraid_isr(int irq, void *dev_id)
pinstance->int_regs.ioa_host_interrupt_clr_reg);

tasklet_schedule(
- &(pinstance->isr_tasklet[hrrq_id]));
+ &(pinstance->isr_tasklet[hrrq_id].tasklet));
}
}

@@ -4380,20 +4380,20 @@ static void pmcraid_worker_function(struct work_struct *workp)
* Return Value
* None
*/
-static void pmcraid_tasklet_function(unsigned long instance)
+static void pmcraid_tasklet_function(struct tasklet_struct *t)
{
- struct pmcraid_isr_param *hrrq_vector;
- struct pmcraid_instance *pinstance;
+ struct pmcraid_tsk_param *tsk_param = from_tasklet(tsk_param, t,
+ tasklet);
+ int id = tsk_param->isr_tasklet_id;
+ struct pmcraid_instance *pinstance = container_of(tsk_param,
+ typeof(*pinstance),
+ isr_tasklet[id]);
unsigned long hrrq_lock_flags;
unsigned long pending_lock_flags;
unsigned long host_lock_flags;
spinlock_t *lockp; /* hrrq buffer lock */
- int id;
u32 resp;

- hrrq_vector = (struct pmcraid_isr_param *)instance;
- pinstance = hrrq_vector->drv_inst;
- id = hrrq_vector->hrrq_id;
lockp = &(pinstance->hrrq_lock[id]);

/* loop through each of the commands responded by IOA. Each HRRQ buf is
@@ -4882,10 +4882,11 @@ static int pmcraid_allocate_config_buffers(struct pmcraid_instance *pinstance)
static void pmcraid_init_tasklets(struct pmcraid_instance *pinstance)
{
int i;
- for (i = 0; i < pinstance->num_hrrq; i++)
- tasklet_init(&pinstance->isr_tasklet[i],
- pmcraid_tasklet_function,
- (unsigned long)&pinstance->hrrq_vector[i]);
+ for (i = 0; i < pinstance->num_hrrq; i++) {
+ pinstance->isr_tasklet[i].isr_tasklet_id = i;
+ tasklet_setup(&pinstance->isr_tasklet[i].tasklet,
+ pmcraid_tasklet_function);
+ }
}

/**
@@ -4900,7 +4901,7 @@ static void pmcraid_kill_tasklets(struct pmcraid_instance *pinstance)
{
int i;
for (i = 0; i < pinstance->num_hrrq; i++)
- tasklet_kill(&pinstance->isr_tasklet[i]);
+ tasklet_kill(&pinstance->isr_tasklet[i].tasklet);
}

/**
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h
index 15c962108075..68dab849d4c1 100644
--- a/drivers/scsi/pmcraid.h
+++ b/drivers/scsi/pmcraid.h
@@ -617,6 +617,11 @@ struct pmcraid_isr_param {
u8 hrrq_id; /* hrrq entry index */
};

+/* Tasklet parameters (one for each enabled tasklet) */
+struct pmcraid_tsk_param {
+ struct tasklet_struct tasklet;
+ u8 isr_tasklet_id; /* isr_tasklet entry index */
+};

/* AEN message header sent as part of event data to applications */
struct pmcraid_aen_msg {
@@ -752,8 +757,8 @@ struct pmcraid_instance {
spinlock_t free_pool_lock; /* free pool lock */
spinlock_t pending_pool_lock; /* pending pool lock */

- /* Tasklet to handle deferred processing */
- struct tasklet_struct isr_tasklet[PMCRAID_NUM_MSIX_VECTORS];
+ /* Tasklet parameters and tasklets to handle deferred processing */
+ struct pmcraid_tsk_param isr_tasklet[PMCRAID_NUM_MSIX_VECTORS];

/* Work-queue (Shared) for deferred reset processing */
struct work_struct worker_q;
--
2.17.1

2020-08-17 08:56:41

by Allen Pais

[permalink] [raw]
Subject: [PATCH 6/8] scsi: mvsas: convert tasklets to use new tasklet_setup() API

From: Allen Pais <[email protected]>

In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.

Signed-off-by: Romain Perier <[email protected]>
Signed-off-by: Allen Pais <[email protected]>
---
drivers/scsi/mvsas/mv_init.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
index 978f5283c883..53b2d463fa13 100644
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -147,13 +147,14 @@ static void mvs_free(struct mvs_info *mvi)
}

#ifdef CONFIG_SCSI_MVSAS_TASKLET
-static void mvs_tasklet(unsigned long opaque)
+static void mvs_tasklet(struct tasklet_struct *t)
{
u32 stat;
u16 core_nr, i = 0;

struct mvs_info *mvi;
- struct sas_ha_struct *sha = (struct sas_ha_struct *)opaque;
+ struct mvs_prv_info *mpi = from_tasklet(mpi, t, mv_tasklet);
+ struct sas_ha_struct *sha = pci_get_drvdata(mpi->mvi[0]->pdev);

core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host;
mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0];
@@ -564,8 +565,7 @@ static int mvs_pci_init(struct pci_dev *pdev, const struct pci_device_id *ent)
} while (nhost < chip->n_host);
mpi = (struct mvs_prv_info *)(SHOST_TO_SAS_HA(shost)->lldd_ha);
#ifdef CONFIG_SCSI_MVSAS_TASKLET
- tasklet_init(&(mpi->mv_tasklet), mvs_tasklet,
- (unsigned long)SHOST_TO_SAS_HA(shost));
+ tasklet_setup(&(mpi->mv_tasklet), mvs_tasklet);
#endif

mvs_post_sas_ha_init(shost, chip);
--
2.17.1

2020-08-17 08:56:59

by Allen Pais

[permalink] [raw]
Subject: [PATCH 5/8] scsi: megaraid: convert tasklets to use new tasklet_setup() API

From: Allen Pais <[email protected]>

In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.

Signed-off-by: Romain Perier <[email protected]>
Signed-off-by: Allen Pais <[email protected]>
---
drivers/scsi/megaraid/megaraid_mbox.c | 9 ++++-----
drivers/scsi/megaraid/megaraid_sas.h | 2 +-
drivers/scsi/megaraid/megaraid_sas_base.c | 16 +++++++---------
drivers/scsi/megaraid/megaraid_sas_fusion.c | 14 +++++++-------
4 files changed, 19 insertions(+), 22 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index 19469a2c0ea3..47b2d8045c9d 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -119,7 +119,7 @@ static void megaraid_mbox_prepare_epthru(adapter_t *, scb_t *,

static irqreturn_t megaraid_isr(int, void *);

-static void megaraid_mbox_dpc(unsigned long);
+static void megaraid_mbox_dpc(struct tasklet_struct *t);

static ssize_t megaraid_sysfs_show_app_hndl(struct device *, struct device_attribute *attr, char *);
static ssize_t megaraid_sysfs_show_ldnum(struct device *, struct device_attribute *attr, char *);
@@ -878,8 +878,7 @@ megaraid_init_mbox(adapter_t *adapter)
}

// setup tasklet for DPC
- tasklet_init(&adapter->dpc_h, megaraid_mbox_dpc,
- (unsigned long)adapter);
+ tasklet_setup(&adapter->dpc_h, megaraid_mbox_dpc);

con_log(CL_DLEVEL1, (KERN_INFO
"megaraid mbox hba successfully initialized\n"));
@@ -2168,9 +2167,9 @@ megaraid_isr(int irq, void *devp)
* it is being called.
*/
static void
-megaraid_mbox_dpc(unsigned long devp)
+megaraid_mbox_dpc(struct tasklet_struct *t)
{
- adapter_t *adapter = (adapter_t *)devp;
+ adapter_t *adapter = from_tasklet(adapter, t, dpc_h);
mraid_device_t *raid_dev;
struct list_head clist;
struct scatterlist *sgl;
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 5e4137f10e0e..ce361b2b9f14 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2531,7 +2531,7 @@ struct megasas_instance_template {
int (*check_reset)(struct megasas_instance *, \
struct megasas_register_set __iomem *);
irqreturn_t (*service_isr)(int irq, void *devp);
- void (*tasklet)(unsigned long);
+ void (*tasklet)(struct tasklet_struct *t);
u32 (*init_adapter)(struct megasas_instance *);
u32 (*build_and_issue_cmd) (struct megasas_instance *,
struct scsi_cmnd *);
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 861f7140f52e..dba60cc1cf41 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -217,7 +217,7 @@ megasas_init_adapter_mfi(struct megasas_instance *instance);
u32
megasas_build_and_issue_cmd(struct megasas_instance *instance,
struct scsi_cmnd *scmd);
-static void megasas_complete_cmd_dpc(unsigned long instance_addr);
+static void megasas_complete_cmd_dpc(struct tasklet_struct *t);
int
wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd,
int seconds);
@@ -2217,14 +2217,14 @@ megasas_check_and_restore_queue_depth(struct megasas_instance *instance)
*
* Tasklet to complete cmds
*/
-static void megasas_complete_cmd_dpc(unsigned long instance_addr)
+static void megasas_complete_cmd_dpc(struct tasklet_struct *t)
{
u32 producer;
u32 consumer;
u32 context;
struct megasas_cmd *cmd;
- struct megasas_instance *instance =
- (struct megasas_instance *)instance_addr;
+ struct megasas_instance *instance = from_tasklet(instance, t,
+ isr_tasklet);
unsigned long flags;

/* If we have already declared adapter dead, donot complete cmds */
@@ -2769,7 +2769,7 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
* Call cmd completion routine. Cmd to be
* be completed directly without depending on isr.
*/
- megasas_complete_cmd_dpc((unsigned long)instance);
+ megasas_complete_cmd_dpc(&instance->isr_tasklet);
}

msleep(1000);
@@ -6180,8 +6180,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
dev_info(&instance->pdev->dev,
"RDPQ mode\t: (%s)\n", instance->is_rdpq ? "enabled" : "disabled");

- tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
- (unsigned long)instance);
+ tasklet_setup(&instance->isr_tasklet, instance->instancet->tasklet);

/*
* Below are default value for legacy Firmware.
@@ -7719,8 +7718,7 @@ megasas_resume(struct pci_dev *pdev)
if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS)
goto fail_init_mfi;

- tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
- (unsigned long)instance);
+ tasklet_setup(&instance->isr_tasklet, instance->instancet->tasklet);

if (instance->msix_vectors ?
megasas_setup_irqs_msix(instance, 0) :
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 0824410f78f8..67b07660971a 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -3705,15 +3705,15 @@ int megasas_irqpoll(struct irq_poll *irqpoll, int budget)

/**
* megasas_complete_cmd_dpc_fusion - Completes command
- * @instance_addr: Adapter soft state address
+ * @t: Instance of the tasklet being run
*
* Tasklet to complete cmds
*/
static void
-megasas_complete_cmd_dpc_fusion(unsigned long instance_addr)
+megasas_complete_cmd_dpc_fusion(struct tasklet_struct *t)
{
- struct megasas_instance *instance =
- (struct megasas_instance *)instance_addr;
+ struct megasas_instance *instance = from_tasklet(instance, t,
+ isr_tasklet);
u32 count, MSIxIndex;

count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
@@ -4062,7 +4062,7 @@ megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
if (reason == MFI_IO_TIMEOUT_OCR) {
dev_info(&instance->pdev->dev,
"MFI command is timed out\n");
- megasas_complete_cmd_dpc_fusion((unsigned long)instance);
+ megasas_complete_cmd_dpc_fusion(&instance->isr_tasklet);
if (instance->snapdump_wait_time)
megasas_trigger_snap_dump(instance);
retval = 1;
@@ -4078,7 +4078,7 @@ megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
"FW in FAULT state Fault code:0x%x subcode:0x%x func:%s\n",
abs_state & MFI_STATE_FAULT_CODE,
abs_state & MFI_STATE_FAULT_SUBCODE, __func__);
- megasas_complete_cmd_dpc_fusion((unsigned long)instance);
+ megasas_complete_cmd_dpc_fusion(&instance->isr_tasklet);
if (instance->requestorId && reason) {
dev_warn(&instance->pdev->dev, "SR-IOV Found FW in FAULT"
" state while polling during"
@@ -4122,7 +4122,7 @@ megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
}
}

- megasas_complete_cmd_dpc_fusion((unsigned long)instance);
+ megasas_complete_cmd_dpc_fusion(&instance->isr_tasklet);
outstanding = atomic_read(&instance->fw_outstanding);
if (!outstanding)
goto out;
--
2.17.1

2020-08-17 08:57:28

by Allen Pais

[permalink] [raw]
Subject: [PATCH 1/8] scsi: aic94xx: convert tasklets to use new tasklet_setup() API

From: Allen Pais <[email protected]>

In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.

Signed-off-by: Romain Perier <[email protected]>
Signed-off-by: Allen Pais <[email protected]>
---
drivers/scsi/aic94xx/aic94xx_hwi.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c
index 9256ab7b2522..1e4d32246cb9 100644
--- a/drivers/scsi/aic94xx/aic94xx_hwi.c
+++ b/drivers/scsi/aic94xx/aic94xx_hwi.c
@@ -248,7 +248,7 @@ static void asd_get_max_scb_ddb(struct asd_ha_struct *asd_ha)

/* ---------- Done List initialization ---------- */

-static void asd_dl_tasklet_handler(unsigned long);
+static void asd_dl_tasklet_handler(struct tasklet_struct *t);

static int asd_init_dl(struct asd_ha_struct *asd_ha)
{
@@ -261,8 +261,7 @@ static int asd_init_dl(struct asd_ha_struct *asd_ha)
asd_ha->seq.dl = asd_ha->seq.actual_dl->vaddr;
asd_ha->seq.dl_toggle = ASD_DEF_DL_TOGGLE;
asd_ha->seq.dl_next = 0;
- tasklet_init(&asd_ha->seq.dl_tasklet, asd_dl_tasklet_handler,
- (unsigned long) asd_ha);
+ tasklet_setup(&asd_ha->seq.dl_tasklet, asd_dl_tasklet_handler);

return 0;
}
@@ -711,9 +710,9 @@ static void asd_chip_reset(struct asd_ha_struct *asd_ha)

/* ---------- Done List Routines ---------- */

-static void asd_dl_tasklet_handler(unsigned long data)
+static void asd_dl_tasklet_handler(struct tasklet_struct *t)
{
- struct asd_ha_struct *asd_ha = (struct asd_ha_struct *) data;
+ struct asd_ha_struct *asd_ha = from_tasklet(asd_ha, t, seq.dl_tasklet);
struct asd_seq_data *seq = &asd_ha->seq;
unsigned long flags;

--
2.17.1

2020-08-17 08:57:45

by Allen Pais

[permalink] [raw]
Subject: [PATCH 3/8] scsi: ibmvscsi: convert tasklets to use new tasklet_setup() API

From: Allen Pais <[email protected]>

In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.

Signed-off-by: Romain Perier <[email protected]>
Signed-off-by: Allen Pais <[email protected]>
---
drivers/scsi/ibmvscsi/ibmvfc.c | 6 +++---
drivers/scsi/ibmvscsi/ibmvscsi.c | 8 ++++----
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 7 +++----
3 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 77f4d37d5bd6..50f025cdabbd 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -3204,9 +3204,9 @@ static irqreturn_t ibmvfc_interrupt(int irq, void *dev_instance)
* Returns:
* Nothing
**/
-static void ibmvfc_tasklet(void *data)
+static void ibmvfc_tasklet(struct tasklet_struct *t)
{
- struct ibmvfc_host *vhost = data;
+ struct ibmvfc_host *vhost = from_tasklet(vhost, t, tasklet);
struct vio_dev *vdev = to_vio_dev(vhost->dev);
struct ibmvfc_crq *crq;
struct ibmvfc_async_crq *async;
@@ -4676,7 +4676,7 @@ static int ibmvfc_init_crq(struct ibmvfc_host *vhost)

retrc = 0;

- tasklet_init(&vhost->tasklet, (void *)ibmvfc_tasklet, (unsigned long)vhost);
+ tasklet_setup(&vhost->tasklet, (void *)ibmvfc_tasklet);

if ((rc = request_irq(vdev->irq, ibmvfc_interrupt, 0, IBMVFC_NAME, vhost))) {
dev_err(dev, "Couldn't register irq 0x%x. rc=%d\n", vdev->irq, rc);
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index b1f3017b6547..46b818daa957 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -208,9 +208,10 @@ static int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata,
* ibmvscsi_task: - Process srps asynchronously
* @data: ibmvscsi_host_data of host
*/
-static void ibmvscsi_task(void *data)
+static void ibmvscsi_task(struct tasklet_struct *t)
{
- struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data;
+ struct ibmvscsi_host_data *hostdata = from_tasklet(hostdata, t,
+ srp_task);
struct vio_dev *vdev = to_vio_dev(hostdata->dev);
struct viosrp_crq *crq;
int done = 0;
@@ -366,8 +367,7 @@ static int ibmvscsi_init_crq_queue(struct crq_queue *queue,
queue->cur = 0;
spin_lock_init(&queue->lock);

- tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task,
- (unsigned long)hostdata);
+ tasklet_setup(&hostdata->srp_task, ibmvscsi_task);

if (request_irq(vdev->irq,
ibmvscsi_handle_event,
diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
index d9e94e81da01..e62fd6c67001 100644
--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -3328,9 +3328,9 @@ static int ibmvscsis_rdma(struct ibmvscsis_cmd *cmd, struct scatterlist *sg,
*
* Note: this is an edge triggered interrupt. It can not be shared.
*/
-static void ibmvscsis_handle_crq(unsigned long data)
+static void ibmvscsis_handle_crq(struct tasklet_struct *t)
{
- struct scsi_info *vscsi = (struct scsi_info *)data;
+ struct scsi_info *vscsi = from_tasklet(vscsi, t, work_task);
struct viosrp_crq *crq;
long rc;
bool ack = true;
@@ -3541,8 +3541,7 @@ static int ibmvscsis_probe(struct vio_dev *vdev,
dev_dbg(&vscsi->dev, "probe hrc %ld, client partition num %d\n",
hrc, vscsi->client_data.partition_number);

- tasklet_init(&vscsi->work_task, ibmvscsis_handle_crq,
- (unsigned long)vscsi);
+ tasklet_setup(&vscsi->work_task, ibmvscsis_handle_crq);

init_completion(&vscsi->wait_idle);
init_completion(&vscsi->unconfig);
--
2.17.1

2020-08-17 08:57:53

by Allen Pais

[permalink] [raw]
Subject: [PATCH 4/8] scsi: isci: convert tasklets to use new tasklet_setup() API

From: Allen Pais <[email protected]>

In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.

Signed-off-by: Romain Perier <[email protected]>
Signed-off-by: Allen Pais <[email protected]>
---
drivers/scsi/isci/host.c | 4 ++--
drivers/scsi/isci/host.h | 2 +-
drivers/scsi/isci/init.c | 3 +--
3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 7b5deae68d33..599adebd039e 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1113,9 +1113,9 @@ void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_ta
* @data: This parameter specifies the ISCI host object
*
*/
-void isci_host_completion_routine(unsigned long data)
+void isci_host_completion_routine(struct tasklet_struct *t)
{
- struct isci_host *ihost = (struct isci_host *)data;
+ struct isci_host *ihost = from_tasklet(ihost, t, completion_tasklet);
u16 active;

spin_lock_irq(&ihost->scic_lock);
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
index 6bc3f022630a..6abe23682d9b 100644
--- a/drivers/scsi/isci/host.h
+++ b/drivers/scsi/isci/host.h
@@ -478,7 +478,7 @@ void isci_tci_free(struct isci_host *ihost, u16 tci);
void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_task *task);

int isci_host_init(struct isci_host *);
-void isci_host_completion_routine(unsigned long data);
+void isci_host_completion_routine(struct tasklet_struct *t);
void isci_host_deinit(struct isci_host *);
void sci_controller_disable_interrupts(struct isci_host *ihost);
bool sci_controller_has_remote_devices_stopping(struct isci_host *ihost);
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
index 085e285f427d..32a0117b5ff4 100644
--- a/drivers/scsi/isci/init.c
+++ b/drivers/scsi/isci/init.c
@@ -511,8 +511,7 @@ static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id)
init_waitqueue_head(&ihost->eventq);
ihost->sas_ha.dev = &ihost->pdev->dev;
ihost->sas_ha.lldd_ha = ihost;
- tasklet_init(&ihost->completion_tasklet,
- isci_host_completion_routine, (unsigned long)ihost);
+ tasklet_setup(&ihost->completion_tasklet, isci_host_completion_routine);

/* validate module parameters */
/* TODO: kill struct sci_user_parameters and reference directly */
--
2.17.1

2020-08-17 08:57:58

by Allen Pais

[permalink] [raw]
Subject: [PATCH 7/8] scsi: pm8001: convert tasklets to use new tasklet_setup() API

From: Allen Pais <[email protected]>

In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.

Signed-off-by: Romain Perier <[email protected]>
Signed-off-by: Allen Pais <[email protected]>
---
drivers/scsi/pm8001/pm8001_init.c | 55 ++++++++++++++++++-------------
drivers/scsi/pm8001/pm8001_sas.h | 6 +++-
2 files changed, 37 insertions(+), 24 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index 20fa96cbc9d3..818816c8b295 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -187,12 +187,15 @@ static void pm8001_free(struct pm8001_hba_info *pm8001_ha)
* @opaque: the passed general host adapter struct
* Note: pm8001_tasklet is common for pm8001 & pm80xx
*/
-static void pm8001_tasklet(unsigned long opaque)
+static void pm8001_tasklet(struct tasklet_struct *t)
{
- struct pm8001_hba_info *pm8001_ha;
+ struct tsk_param *tsk_param = from_tasklet(tsk_param, t, tasklet);
+ struct pm8001_hba_info *pm8001_ha = container_of(tsk_param,
+ typeof(*pm8001_ha),
+ tasklet[tsk_param->irq_id]);
struct isr_param *irq_vector;

- irq_vector = (struct isr_param *)opaque;
+ irq_vector = &pm8001_ha->irq_vector[tsk_param->irq_id];
pm8001_ha = irq_vector->drv_inst;
if (unlikely(!pm8001_ha))
BUG_ON(1);
@@ -221,7 +224,7 @@ static irqreturn_t pm8001_interrupt_handler_msix(int irq, void *opaque)
if (!PM8001_CHIP_DISP->is_our_interrupt(pm8001_ha))
return IRQ_NONE;
#ifdef PM8001_USE_TASKLET
- tasklet_schedule(&pm8001_ha->tasklet[irq_vector->irq_id]);
+ tasklet_schedule(&pm8001_ha->tasklet[irq_vector->irq_id].tasklet);
#else
ret = PM8001_CHIP_DISP->isr(pm8001_ha, irq_vector->irq_id);
#endif
@@ -246,7 +249,7 @@ static irqreturn_t pm8001_interrupt_handler_intx(int irq, void *dev_id)
return IRQ_NONE;

#ifdef PM8001_USE_TASKLET
- tasklet_schedule(&pm8001_ha->tasklet[0]);
+ tasklet_schedule(&pm8001_ha->tasklet[0].tasklet);
#else
ret = PM8001_CHIP_DISP->isr(pm8001_ha, 0);
#endif
@@ -507,13 +510,16 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev,
#ifdef PM8001_USE_TASKLET
/* Tasklet for non msi-x interrupt handler */
if ((!pdev->msix_cap || !pci_msi_enabled())
- || (pm8001_ha->chip_id == chip_8001))
- tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet,
- (unsigned long)&(pm8001_ha->irq_vector[0]));
- else
- for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
- tasklet_init(&pm8001_ha->tasklet[j], pm8001_tasklet,
- (unsigned long)&(pm8001_ha->irq_vector[j]));
+ || (pm8001_ha->chip_id == chip_8001)) {
+ pm8001_ha->tasklet[0].irq_id = 0;
+ tasklet_setup(&pm8001_ha->tasklet[0].tasklet, pm8001_tasklet);
+ } else {
+ for (j = 0; j < PM8001_MAX_MSIX_VEC; j++) {
+ pm8001_ha->tasklet[j].irq_id = j;
+ tasklet_setup(&pm8001_ha->tasklet[j].tasklet,
+ pm8001_tasklet);
+ }
+ }
#endif
pm8001_ioremap(pm8001_ha);
if (!pm8001_alloc(pm8001_ha, ent))
@@ -1162,10 +1168,10 @@ static void pm8001_pci_remove(struct pci_dev *pdev)
/* For non-msix and msix interrupts */
if ((!pdev->msix_cap || !pci_msi_enabled()) ||
(pm8001_ha->chip_id == chip_8001))
- tasklet_kill(&pm8001_ha->tasklet[0]);
+ tasklet_kill(&pm8001_ha->tasklet[0].tasklet);
else
for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
- tasklet_kill(&pm8001_ha->tasklet[j]);
+ tasklet_kill(&pm8001_ha->tasklet[j].tasklet);
#endif
scsi_host_put(pm8001_ha->shost);
pm8001_free(pm8001_ha);
@@ -1212,10 +1218,10 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state)
/* For non-msix and msix interrupts */
if ((!pdev->msix_cap || !pci_msi_enabled()) ||
(pm8001_ha->chip_id == chip_8001))
- tasklet_kill(&pm8001_ha->tasklet[0]);
+ tasklet_kill(&pm8001_ha->tasklet[0].tasklet);
else
for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
- tasklet_kill(&pm8001_ha->tasklet[j]);
+ tasklet_kill(&pm8001_ha->tasklet[j].tasklet);
#endif
device_state = pci_choose_state(pdev, state);
pm8001_printk("pdev=0x%p, slot=%s, entering "
@@ -1281,13 +1287,16 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
#ifdef PM8001_USE_TASKLET
/* Tasklet for non msi-x interrupt handler */
if ((!pdev->msix_cap || !pci_msi_enabled()) ||
- (pm8001_ha->chip_id == chip_8001))
- tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet,
- (unsigned long)&(pm8001_ha->irq_vector[0]));
- else
- for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
- tasklet_init(&pm8001_ha->tasklet[j], pm8001_tasklet,
- (unsigned long)&(pm8001_ha->irq_vector[j]));
+ (pm8001_ha->chip_id == chip_8001)) {
+ pm8001_ha->tasklet[0].irq_id = 0;
+ tasklet_setup(&pm8001_ha->tasklet[0].tasklet, pm8001_tasklet);
+ } else {
+ for (j = 0; j < PM8001_MAX_MSIX_VEC; j++) {
+ pm8001_ha->tasklet[j].irq_id = j;
+ tasklet_setup(&pm8001_ha->tasklet[j].tasklet,
+ pm8001_tasklet);
+ }
+ }
#endif
PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, 0);
if (pm8001_ha->chip_id != chip_8001) {
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index ae7ba9b3c4bc..6dbaa394a08b 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -494,6 +494,10 @@ struct isr_param {
struct pm8001_hba_info *drv_inst;
u32 irq_id;
};
+struct tsk_param {
+ struct tasklet_struct tasklet;
+ u32 irq_id;
+};
struct pm8001_hba_info {
char name[PM8001_NAME_LENGTH];
struct list_head list;
@@ -549,7 +553,7 @@ struct pm8001_hba_info {
[PM8001_NAME_LENGTH+1+3+1];
#endif
#ifdef PM8001_USE_TASKLET
- struct tasklet_struct tasklet[PM8001_MAX_MSIX_VEC];
+ struct tsk_param tasklet[PM8001_MAX_MSIX_VEC];
#endif
u32 logging_level;
u32 link_rate;
--
2.17.1

2020-08-17 14:46:17

by James Bottomley

[permalink] [raw]
Subject: Re: [PATCH 0/8] scsi: convert tasklets to use new tasklet_setup()

On Mon, 2020-08-17 at 14:24 +0530, Allen Pais wrote:
> From: Allen Pais <[email protected]>
>
> Commit 12cc923f1ccc ("tasklet: Introduce new initialization API")'
> introduced a new tasklet initialization API. This series converts
> all the scsi drivers to use the new tasklet_setup() API

I've got to say I agree with Jens, this was a silly obfuscation:

+#define from_tasklet(var, callback_tasklet, tasklet_fieldname) \
+ container_of(callback_tasklet, typeof(*var), tasklet_fieldname)

Just use container_of directly since we all understand what it does.

James

2020-08-17 19:59:40

by James Bottomley

[permalink] [raw]
Subject: Re: [PATCH 0/8] scsi: convert tasklets to use new tasklet_setup()

On Mon, 2020-08-17 at 12:28 -0700, Kees Cook wrote:
> On Mon, Aug 17, 2020 at 07:41:58AM -0700, James Bottomley wrote:
> > On Mon, 2020-08-17 at 14:24 +0530, Allen Pais wrote:
> > > From: Allen Pais <[email protected]>
> > >
> > > Commit 12cc923f1ccc ("tasklet: Introduce new initialization
> > > API")' introduced a new tasklet initialization API. This series
> > > converts all the scsi drivers to use the new tasklet_setup() API
> >
> > I've got to say I agree with Jens, this was a silly obfuscation:
> >
> > +#define from_tasklet(var, callback_tasklet, tasklet_fieldname) \
> > + container_of(callback_tasklet, typeof(*var),
> > tasklet_fieldname)
> >
> > Just use container_of directly since we all understand what it
> > does.
>
> But then the lines get really long, wrapped, etc.

I really don't think that's a problem but if you want to add a new
generic container_of that does typeof instead of insisting on the type,
I'd be sort of OK with that ... provided you don't gratuitously alter
the argument order.

The thing I object to is that this encourages everyone to roll their
own unnecessary container_of type macros in spite of the fact that it's
function is wholly generic. It's fine if you're eliminating one of the
arguments, or actually making the macro specific to the type, but in
this case you're not, you're making a completely generic macro where
the name is the only thing that's specific to this case.

> This is what the timer_struct conversion did too (added a
> container_of wrapper), so I think it makes sense here too.

I didn't see that one to object to it ...

James

2020-08-17 22:54:20

by Kees Cook

[permalink] [raw]
Subject: Re: [PATCH 0/8] scsi: convert tasklets to use new tasklet_setup()

On Mon, Aug 17, 2020 at 07:41:58AM -0700, James Bottomley wrote:
> On Mon, 2020-08-17 at 14:24 +0530, Allen Pais wrote:
> > From: Allen Pais <[email protected]>
> >
> > Commit 12cc923f1ccc ("tasklet: Introduce new initialization API")'
> > introduced a new tasklet initialization API. This series converts
> > all the scsi drivers to use the new tasklet_setup() API
>
> I've got to say I agree with Jens, this was a silly obfuscation:
>
> +#define from_tasklet(var, callback_tasklet, tasklet_fieldname) \
> + container_of(callback_tasklet, typeof(*var), tasklet_fieldname)
>
> Just use container_of directly since we all understand what it does.

But then the lines get really long, wrapped, etc. This is what the
timer_struct conversion did too (added a container_of wrapper), so I
think it makes sense here too.

--
Kees Cook

2020-09-01 10:08:11

by Allen

[permalink] [raw]
Subject: Re: [PATCH 0/8] scsi: convert tasklets to use new tasklet_setup()

> > > >
> > > > Commit 12cc923f1ccc ("tasklet: Introduce new initialization
> > > > API")' introduced a new tasklet initialization API. This series
> > > > converts all the scsi drivers to use the new tasklet_setup() API
> > >
> > > I've got to say I agree with Jens, this was a silly obfuscation:
> > >
> > > +#define from_tasklet(var, callback_tasklet, tasklet_fieldname) \
> > > + container_of(callback_tasklet, typeof(*var),
> > > tasklet_fieldname)
> > >
> > > Just use container_of directly since we all understand what it
> > > does.
> >
> > But then the lines get really long, wrapped, etc.
>
> I really don't think that's a problem but if you want to add a new
> generic container_of that does typeof instead of insisting on the type,
> I'd be sort of OK with that ... provided you don't gratuitously alter
> the argument order.
>
> The thing I object to is that this encourages everyone to roll their
> own unnecessary container_of type macros in spite of the fact that it's
> function is wholly generic. It's fine if you're eliminating one of the
> arguments, or actually making the macro specific to the type, but in
> this case you're not, you're making a completely generic macro where
> the name is the only thing that's specific to this case.
>
> > This is what the timer_struct conversion did too (added a
> > container_of wrapper), so I think it makes sense here too.
>
> I didn't see that one to object to it ...

Since we could not get the generic API accepted, can I send out V2
which would use container_of()?

Thanks,

--
- Allen