Skip to content

Commit

Permalink
Merge branch 'fixes' into for-next
Browse files Browse the repository at this point in the history
  • Loading branch information
James Bottomley authored and James Bottomley committed Jul 30, 2021
2 parents 08dc2f9 + f0f82e2 commit 3c89644
Show file tree
Hide file tree
Showing 14 changed files with 137 additions and 124 deletions.
4 changes: 2 additions & 2 deletions drivers/scsi/device_handler/scsi_dh_rdac.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,8 +453,8 @@ static int initialize_controller(struct scsi_device *sdev,
if (!h->ctlr)
err = SCSI_DH_RES_TEMP_UNAVAIL;
else {
list_add_rcu(&h->node, &h->ctlr->dh_list);
h->sdev = sdev;
list_add_rcu(&h->node, &h->ctlr->dh_list);
}
spin_unlock(&list_lock);
err = SCSI_DH_OK;
Expand Down Expand Up @@ -778,11 +778,11 @@ static void rdac_bus_detach( struct scsi_device *sdev )
spin_lock(&list_lock);
if (h->ctlr) {
list_del_rcu(&h->node);
h->sdev = NULL;
kref_put(&h->ctlr->kref, release_controller);
}
spin_unlock(&list_lock);
sdev->handler_data = NULL;
synchronize_rcu();
kfree(h);
}

Expand Down
19 changes: 17 additions & 2 deletions drivers/scsi/ibmvscsi/ibmvfc.c
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,13 @@ static int ibmvfc_init_event_pool(struct ibmvfc_host *vhost,
for (i = 0; i < size; ++i) {
struct ibmvfc_event *evt = &pool->events[i];

/*
* evt->active states
* 1 = in flight
* 0 = being completed
* -1 = free/freed
*/
atomic_set(&evt->active, -1);
atomic_set(&evt->free, 1);
evt->crq.valid = 0x80;
evt->crq.ioba = cpu_to_be64(pool->iu_token + (sizeof(*evt->xfer_iu) * i));
Expand Down Expand Up @@ -1017,6 +1024,7 @@ static void ibmvfc_free_event(struct ibmvfc_event *evt)

BUG_ON(!ibmvfc_valid_event(pool, evt));
BUG_ON(atomic_inc_return(&evt->free) != 1);
BUG_ON(atomic_dec_and_test(&evt->active));

spin_lock_irqsave(&evt->queue->l_lock, flags);
list_add_tail(&evt->queue_list, &evt->queue->free);
Expand Down Expand Up @@ -1072,6 +1080,12 @@ static void ibmvfc_complete_purge(struct list_head *purge_list)
**/
static void ibmvfc_fail_request(struct ibmvfc_event *evt, int error_code)
{
/*
* Anything we are failing should still be active. Otherwise, it
* implies we already got a response for the command and are doing
* something bad like double completing it.
*/
BUG_ON(!atomic_dec_and_test(&evt->active));
if (evt->cmnd) {
evt->cmnd->result = (error_code << 16);
evt->done = ibmvfc_scsi_eh_done;
Expand Down Expand Up @@ -1723,6 +1737,7 @@ static int ibmvfc_send_event(struct ibmvfc_event *evt,

evt->done(evt);
} else {
atomic_set(&evt->active, 1);
spin_unlock_irqrestore(&evt->queue->l_lock, flags);
ibmvfc_trc_start(evt);
}
Expand Down Expand Up @@ -3251,7 +3266,7 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost,
return;
}

if (unlikely(atomic_read(&evt->free))) {
if (unlikely(atomic_dec_if_positive(&evt->active))) {
dev_err(vhost->dev, "Received duplicate correlation_token 0x%08llx!\n",
crq->ioba);
return;
Expand Down Expand Up @@ -3778,7 +3793,7 @@ static void ibmvfc_handle_scrq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost
return;
}

if (unlikely(atomic_read(&evt->free))) {
if (unlikely(atomic_dec_if_positive(&evt->active))) {
dev_err(vhost->dev, "Received duplicate correlation_token 0x%08llx!\n",
crq->ioba);
return;
Expand Down
1 change: 1 addition & 0 deletions drivers/scsi/ibmvscsi/ibmvfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,7 @@ struct ibmvfc_event {
struct ibmvfc_target *tgt;
struct scsi_cmnd *cmnd;
atomic_t free;
atomic_t active;
union ibmvfc_iu *xfer_iu;
void (*done)(struct ibmvfc_event *evt);
void (*_done)(struct ibmvfc_event *evt);
Expand Down
21 changes: 15 additions & 6 deletions drivers/scsi/megaraid/megaraid_mm.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ mraid_mm_get_adapter(mimd_t __user *umimd, int *rval)
mimd_t mimd;
uint32_t adapno;
int iterator;

bool is_found;

if (copy_from_user(&mimd, umimd, sizeof(mimd_t))) {
*rval = -EFAULT;
Expand All @@ -254,12 +254,16 @@ mraid_mm_get_adapter(mimd_t __user *umimd, int *rval)

adapter = NULL;
iterator = 0;
is_found = false;

list_for_each_entry(adapter, &adapters_list_g, list) {
if (iterator++ == adapno) break;
if (iterator++ == adapno) {
is_found = true;
break;
}
}

if (!adapter) {
if (!is_found) {
*rval = -ENODEV;
return NULL;
}
Expand Down Expand Up @@ -725,6 +729,7 @@ ioctl_done(uioc_t *kioc)
uint32_t adapno;
int iterator;
mraid_mmadp_t* adapter;
bool is_found;

/*
* When the kioc returns from driver, make sure it still doesn't
Expand All @@ -747,19 +752,23 @@ ioctl_done(uioc_t *kioc)
iterator = 0;
adapter = NULL;
adapno = kioc->adapno;
is_found = false;

con_log(CL_ANN, ( KERN_WARNING "megaraid cmm: completed "
"ioctl that was timedout before\n"));

list_for_each_entry(adapter, &adapters_list_g, list) {
if (iterator++ == adapno) break;
if (iterator++ == adapno) {
is_found = true;
break;
}
}

kioc->timedout = 0;

if (adapter) {
if (is_found)
mraid_mm_dealloc_kioc( adapter, kioc );
}

}
else {
wake_up(&wait_q);
Expand Down
32 changes: 16 additions & 16 deletions drivers/scsi/mpt3sas/mpt3sas_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -2983,13 +2983,13 @@ _base_check_enable_msix(struct MPT3SAS_ADAPTER *ioc)
}

/**
* _base_free_irq - free irq
* mpt3sas_base_free_irq - free irq
* @ioc: per adapter object
*
* Freeing respective reply_queue from the list.
*/
static void
_base_free_irq(struct MPT3SAS_ADAPTER *ioc)
void
mpt3sas_base_free_irq(struct MPT3SAS_ADAPTER *ioc)
{
struct adapter_reply_queue *reply_q, *next;

Expand Down Expand Up @@ -3191,12 +3191,12 @@ _base_check_and_enable_high_iops_queues(struct MPT3SAS_ADAPTER *ioc,
}

/**
* _base_disable_msix - disables msix
* mpt3sas_base_disable_msix - disables msix
* @ioc: per adapter object
*
*/
static void
_base_disable_msix(struct MPT3SAS_ADAPTER *ioc)
void
mpt3sas_base_disable_msix(struct MPT3SAS_ADAPTER *ioc)
{
if (!ioc->msix_enable)
return;
Expand Down Expand Up @@ -3304,8 +3304,8 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc)
for (i = 0; i < ioc->reply_queue_count; i++) {
r = _base_request_irq(ioc, i);
if (r) {
_base_free_irq(ioc);
_base_disable_msix(ioc);
mpt3sas_base_free_irq(ioc);
mpt3sas_base_disable_msix(ioc);
goto try_ioapic;
}
}
Expand Down Expand Up @@ -3342,8 +3342,8 @@ mpt3sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc)

dexitprintk(ioc, ioc_info(ioc, "%s\n", __func__));

_base_free_irq(ioc);
_base_disable_msix(ioc);
mpt3sas_base_free_irq(ioc);
mpt3sas_base_disable_msix(ioc);

kfree(ioc->replyPostRegisterIndex);
ioc->replyPostRegisterIndex = NULL;
Expand Down Expand Up @@ -7613,14 +7613,14 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc)
}

/**
* _base_make_ioc_ready - put controller in READY state
* mpt3sas_base_make_ioc_ready - put controller in READY state
* @ioc: per adapter object
* @type: FORCE_BIG_HAMMER or SOFT_RESET
*
* Return: 0 for success, non-zero for failure.
*/
static int
_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type)
int
mpt3sas_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type)
{
u32 ioc_state;
int rc;
Expand Down Expand Up @@ -7897,7 +7897,7 @@ mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc)
if (ioc->chip_phys && ioc->chip) {
mpt3sas_base_mask_interrupts(ioc);
ioc->shost_recovery = 1;
_base_make_ioc_ready(ioc, SOFT_RESET);
mpt3sas_base_make_ioc_ready(ioc, SOFT_RESET);
ioc->shost_recovery = 0;
}

Expand Down Expand Up @@ -8017,7 +8017,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
ioc->build_sg_mpi = &_base_build_sg;
ioc->build_zero_len_sge_mpi = &_base_build_zero_len_sge;

r = _base_make_ioc_ready(ioc, SOFT_RESET);
r = mpt3sas_base_make_ioc_ready(ioc, SOFT_RESET);
if (r)
goto out_free_resources;

Expand Down Expand Up @@ -8471,7 +8471,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
_base_pre_reset_handler(ioc);
mpt3sas_wait_for_commands_to_complete(ioc);
mpt3sas_base_mask_interrupts(ioc);
r = _base_make_ioc_ready(ioc, type);
r = mpt3sas_base_make_ioc_ready(ioc, type);
if (r)
goto out;
_base_clear_outstanding_commands(ioc);
Expand Down
4 changes: 4 additions & 0 deletions drivers/scsi/mpt3sas/mpt3sas_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -1730,6 +1730,10 @@ do { ioc_err(ioc, "In func: %s\n", __func__); \
status, mpi_request, sz); } while (0)

int mpt3sas_wait_for_ioc(struct MPT3SAS_ADAPTER *ioc, int wait_count);
int
mpt3sas_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type);
void mpt3sas_base_free_irq(struct MPT3SAS_ADAPTER *ioc);
void mpt3sas_base_disable_msix(struct MPT3SAS_ADAPTER *ioc);

/* scsih shared API */
struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc,
Expand Down
7 changes: 6 additions & 1 deletion drivers/scsi/mpt3sas/mpt3sas_scsih.c
Original file line number Diff line number Diff line change
Expand Up @@ -11295,7 +11295,12 @@ scsih_shutdown(struct pci_dev *pdev)

_scsih_ir_shutdown(ioc);
_scsih_nvme_shutdown(ioc);
mpt3sas_base_detach(ioc);
mpt3sas_base_mask_interrupts(ioc);
ioc->shost_recovery = 1;
mpt3sas_base_make_ioc_ready(ioc, SOFT_RESET);
ioc->shost_recovery = 0;
mpt3sas_base_free_irq(ioc);
mpt3sas_base_disable_msix(ioc);
}


Expand Down
32 changes: 15 additions & 17 deletions drivers/scsi/pm8001/pm8001_sas.c
Original file line number Diff line number Diff line change
Expand Up @@ -684,18 +684,22 @@ int pm8001_dev_found(struct domain_device *dev)

void pm8001_task_done(struct sas_task *task)
{
if (!del_timer(&task->slow_task->timer))
return;
del_timer(&task->slow_task->timer);
complete(&task->slow_task->completion);
}

static void pm8001_tmf_timedout(struct timer_list *t)
{
struct sas_task_slow *slow = from_timer(slow, t, timer);
struct sas_task *task = slow->task;
unsigned long flags;

task->task_state_flags |= SAS_TASK_STATE_ABORTED;
complete(&task->slow_task->completion);
spin_lock_irqsave(&task->task_state_lock, flags);
if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
task->task_state_flags |= SAS_TASK_STATE_ABORTED;
complete(&task->slow_task->completion);
}
spin_unlock_irqrestore(&task->task_state_lock, flags);
}

#define PM8001_TASK_TIMEOUT 20
Expand Down Expand Up @@ -748,13 +752,10 @@ static int pm8001_exec_internal_tmf_task(struct domain_device *dev,
}
res = -TMF_RESP_FUNC_FAILED;
/* Even TMF timed out, return direct. */
if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
pm8001_dbg(pm8001_ha, FAIL,
"TMF task[%x]timeout.\n",
tmf->tmf);
goto ex_err;
}
if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
pm8001_dbg(pm8001_ha, FAIL, "TMF task[%x]timeout.\n",
tmf->tmf);
goto ex_err;
}

if (task->task_status.resp == SAS_TASK_COMPLETE &&
Expand Down Expand Up @@ -834,12 +835,9 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
wait_for_completion(&task->slow_task->completion);
res = TMF_RESP_FUNC_FAILED;
/* Even TMF timed out, return direct. */
if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
pm8001_dbg(pm8001_ha, FAIL,
"TMF task timeout.\n");
goto ex_err;
}
if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
pm8001_dbg(pm8001_ha, FAIL, "TMF task timeout.\n");
goto ex_err;
}

if (task->task_status.resp == SAS_TASK_COMPLETE &&
Expand Down
3 changes: 2 additions & 1 deletion drivers/scsi/scsi_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,8 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
error = shost->hostt->target_alloc(starget);

if(error) {
dev_printk(KERN_ERR, dev, "target allocation failed, error %d\n", error);
if (error != -ENXIO)
dev_err(dev, "target allocation failed, error %d\n", error);
/* don't want scsi_target_reap to do the final
* put because it will be under the host lock */
scsi_target_destroy(starget);
Expand Down
9 changes: 6 additions & 3 deletions drivers/scsi/scsi_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -807,11 +807,14 @@ store_state_field(struct device *dev, struct device_attribute *attr,
mutex_lock(&sdev->state_mutex);
ret = scsi_device_set_state(sdev, state);
/*
* If the device state changes to SDEV_RUNNING, we need to run
* the queue to avoid I/O hang.
* If the device state changes to SDEV_RUNNING, we need to
* rescan the device to revalidate it, and run the queue to
* avoid I/O hang.
*/
if (ret == 0 && state == SDEV_RUNNING)
if (ret == 0 && state == SDEV_RUNNING) {
scsi_rescan_device(dev);
blk_mq_run_hw_queues(sdev->request_queue, true);
}
mutex_unlock(&sdev->state_mutex);

return ret == 0 ? count : -EINVAL;
Expand Down
Loading

0 comments on commit 3c89644

Please sign in to comment.