Brian King <brk...@linux.vnet.ibm.com> writes: > Removes the free and pending ipr_cmd queues. This is the first patch in a > series > to make queuecommand lockless for the ipr driver. Creates a bitarray for each > hardware queue so we can track whether an ipr_cmd struct is free or not. Also > adds an atomic flag on each ipr_cmd to ensure we don't race between command > completion and error handling.
Nice patch. My main concern is whether we are duplicating functionality from the upper layers. I'm not familiar with scsi-mq, but isn't the timeout/completion race handled by the blk-mq layer? Also, can't the active commands be handled by the tags bitmap? I'm a bit puzzled by this, would be nice if you can explain why we need this design in the low-level driver. > > Signed-off-by: Brian King <brk...@linux.vnet.ibm.com> > --- > > drivers/scsi/ipr.c | 176 > +++++++++++++++++++++-------------------------------- > drivers/scsi/ipr.h | 51 ++++++++++++++- > 2 files changed, 122 insertions(+), 105 deletions(-) > > diff -puN drivers/scsi/ipr.h~ipr_cmd_bitarray drivers/scsi/ipr.h > --- linux-2.6.git/drivers/scsi/ipr.h~ipr_cmd_bitarray 2016-09-05 > 14:44:02.353628212 -0500 > +++ linux-2.6.git-bjking1/drivers/scsi/ipr.h 2016-09-05 15:18:16.881117822 > -0500 > @@ -507,9 +507,8 @@ struct ipr_hrr_queue { > volatile __be32 *hrrq_start; > volatile __be32 *hrrq_end; > volatile __be32 *hrrq_curr; > + unsigned long *active_map; > > - struct list_head hrrq_free_q; > - struct list_head hrrq_pending_q; > struct list_head hrrq_error_q; > spinlock_t _lock; > spinlock_t *lock; > @@ -1621,6 +1620,7 @@ struct ipr_cmnd { > struct list_head queue; > struct scsi_cmnd *scsi_cmd; > struct ata_queued_cmd *qc; > + unsigned long atomic_flags; > struct completion completion; > struct timer_list timer; > struct work_struct work; > @@ -1847,6 +1847,53 @@ ipr_err("------------------------------- > * Inlines > */ > > +enum ipr_atomic_flags { > + IPR_CMD_COMPLETE = 0, > +}; > + > +static inline int ipr_cmnd_complete(struct ipr_cmnd *ipr_cmd) > +{ > + /* xxx may be overkill since completions all occur under the HRRQ lock > */ > + return test_and_set_bit(IPR_CMD_COMPLETE, &ipr_cmd->atomic_flags); If we have to keep this handled in the ipr driver, I don't see this as overkill. > +} > + > +static inline void ipr_cmnd_clear_complete(struct ipr_cmnd *ipr_cmd) > +{ > + clear_bit(IPR_CMD_COMPLETE, &ipr_cmd->atomic_flags); > +} > + > +static inline void ipr_free_cmd(struct ipr_cmnd *ipr_cmd) > +{ > + clear_bit(ipr_cmd->cmd_index - ipr_cmd->hrrq->min_cmd_id, > + ipr_cmd->hrrq->active_map); > +} > + > +static inline struct ipr_cmnd* ipr_first_active_cmd(struct ipr_hrr_queue > *hrrq) > +{ > + int i = find_first_bit(hrrq->active_map, hrrq->size); > + struct ipr_cmnd *ipr_cmd = NULL; > + > + if (i < hrrq->size) > + ipr_cmd = hrrq->ioa_cfg->ipr_cmnd_list[i + hrrq->min_cmd_id]; > + return ipr_cmd; > +} > + > +static inline struct ipr_cmnd* ipr_next_active_cmd(struct ipr_hrr_queue > *hrrq, struct ipr_cmnd *ipr_cmd) > +{ > + int last = ipr_cmd->cmd_index - hrrq->min_cmd_id; > + int i; > + > + i = find_next_bit(hrrq->active_map, hrrq->size, last + 1); > + if (i < hrrq->size) > + return hrrq->ioa_cfg->ipr_cmnd_list[i + hrrq->min_cmd_id]; > + return NULL; > +} > + > +#define for_each_active_cmd(ipr_cmd, hrrq) \ > + for (ipr_cmd = ipr_first_active_cmd(hrrq); \ > + ipr_cmd; \ > + ipr_cmd = ipr_next_active_cmd(hrrq, ipr_cmd)) > + > /** > * ipr_is_ioa_resource - Determine if a resource is the IOA > * @res: resource entry struct > diff -puN drivers/scsi/ipr.c~ipr_cmd_bitarray drivers/scsi/ipr.c > --- linux-2.6.git/drivers/scsi/ipr.c~ipr_cmd_bitarray 2016-09-05 > 14:44:02.357628190 -0500 > +++ linux-2.6.git-bjking1/drivers/scsi/ipr.c 2016-09-05 15:19:21.255759157 > -0500 > @@ -656,6 +656,7 @@ static void ipr_reinit_ipr_cmnd(struct i > dma_addr_t dma_addr = ipr_cmd->dma_addr; > int hrrq_id; > > + ipr_cmnd_clear_complete(ipr_cmd); > hrrq_id = ioarcb->cmd_pkt.hrrq_id; > memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); > ioarcb->cmd_pkt.hrrq_id = hrrq_id; > @@ -711,16 +712,17 @@ static void ipr_init_ipr_cmnd(struct ipr > static > struct ipr_cmnd *__ipr_get_free_ipr_cmnd(struct ipr_hrr_queue *hrrq) > { > - struct ipr_cmnd *ipr_cmd = NULL; > + int index; > > - if (likely(!list_empty(&hrrq->hrrq_free_q))) { > - ipr_cmd = list_entry(hrrq->hrrq_free_q.next, > - struct ipr_cmnd, queue); > - list_del(&ipr_cmd->queue); > - } > + do { > + index = find_first_zero_bit(hrrq->active_map, hrrq->size); > > + if (index == hrrq->size) > + return NULL; > > - return ipr_cmd; > + } while (test_and_set_bit(index, hrrq->active_map)); > + > + return hrrq->ioa_cfg->ipr_cmnd_list[index + hrrq->min_cmd_id]; > } > > /** > @@ -843,7 +845,7 @@ static void ipr_sata_eh_done(struct ipr_ > sata_port->ioasa.status |= ATA_BUSY; > > spin_lock_irqsave(ipr_cmd->hrrq->lock, lock_flags); > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > spin_unlock_irqrestore(ipr_cmd->hrrq->lock, lock_flags); > ata_qc_complete(qc); > } > @@ -869,7 +871,7 @@ static void __ipr_scsi_eh_done(struct ip > if (ipr_cmd->eh_comp) > complete(ipr_cmd->eh_comp); > spin_lock(&ipr_cmd->hrrq->_lock); > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > spin_unlock(&ipr_cmd->hrrq->_lock); > } > > @@ -897,9 +899,6 @@ static void ipr_scsi_eh_done(struct ipr_ > spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); > if (ipr_cmd->eh_comp) > complete(ipr_cmd->eh_comp); > - spin_lock(&ipr_cmd->hrrq->_lock); > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > - spin_unlock(&ipr_cmd->hrrq->_lock); > spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); > } > > @@ -937,27 +936,30 @@ static void ipr_send_back_failed_ops(str > **/ > static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg) > { > - struct ipr_cmnd *ipr_cmd, *temp; > + struct ipr_cmnd *ipr_cmd; > struct ipr_hrr_queue *hrrq; > > ENTER; > for_each_hrrq(hrrq, ioa_cfg) { > spin_lock(&hrrq->_lock); > - list_for_each_entry_safe(ipr_cmd, > - temp, &hrrq->hrrq_pending_q, queue) { > - list_move_tail(&ipr_cmd->queue, &hrrq->hrrq_error_q); > - > - ipr_cmd->s.ioasa.hdr.ioasc = > - cpu_to_be32(IPR_IOASC_IOA_WAS_RESET); > - ipr_cmd->s.ioasa.hdr.ilid = > - cpu_to_be32(IPR_DRIVER_ILID); > - > - if (ipr_cmd->scsi_cmd) > - ipr_cmd->fast_done = ipr_scsi_eh_done; > - else if (ipr_cmd->qc) > - ipr_cmd->fast_done = ipr_sata_eh_done; > + for_each_active_cmd(ipr_cmd, hrrq) { > + if (ipr_cmd == ioa_cfg->reset_cmd) > + continue; > > - del_timer(&ipr_cmd->timer); > + if (!ipr_cmnd_complete(ipr_cmd)) { > + list_add_tail(&ipr_cmd->queue, > &hrrq->hrrq_error_q); > + ipr_cmd->s.ioasa.hdr.ioasc = > + cpu_to_be32(IPR_IOASC_IOA_WAS_RESET); > + ipr_cmd->s.ioasa.hdr.ilid = > + cpu_to_be32(IPR_DRIVER_ILID); > + > + if (ipr_cmd->scsi_cmd) > + ipr_cmd->fast_done = ipr_scsi_eh_done; > + else if (ipr_cmd->qc) > + ipr_cmd->fast_done = ipr_sata_eh_done; > + > + del_timer(&ipr_cmd->timer); > + } > } > spin_unlock(&hrrq->_lock); > } > @@ -1010,8 +1012,6 @@ static void ipr_do_req(struct ipr_cmnd * > void (*done) (struct ipr_cmnd *), > void (*timeout_func) (struct ipr_cmnd *), u32 timeout) > { > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_pending_q); > - > ipr_cmd->done = done; > > ipr_cmd->timer.data = (unsigned long) ipr_cmd; > @@ -1145,7 +1145,6 @@ static void ipr_send_hcam(struct ipr_ioa > > if (ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) { > ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_pending_q); > list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_pending_q); > > ipr_cmd->u.hostrcb = hostrcb; > @@ -1534,7 +1533,7 @@ static void ipr_process_ccn(struct ipr_c > u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); > > list_del_init(&hostrcb->queue); > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > > if (ioasc) { > if (ioasc != IPR_IOASC_IOA_WAS_RESET && > @@ -2654,7 +2653,7 @@ static void ipr_process_error(struct ipr > fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc); > > list_del_init(&hostrcb->queue); > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > > if (!ioasc) { > ipr_handle_log_data(ioa_cfg, hostrcb); > @@ -5075,7 +5074,7 @@ static int ipr_wait_for_ops(struct ipr_i > > for_each_hrrq(hrrq, ioa_cfg) { > spin_lock_irqsave(hrrq->lock, flags); > - list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, > queue) { > + for_each_active_cmd(ipr_cmd, hrrq) { > if (match(ipr_cmd, device)) { > ipr_cmd->eh_comp = ∁ > wait++; > @@ -5092,7 +5091,7 @@ static int ipr_wait_for_ops(struct ipr_i > > for_each_hrrq(hrrq, ioa_cfg) { > spin_lock_irqsave(hrrq->lock, flags); > - list_for_each_entry(ipr_cmd, > &hrrq->hrrq_pending_q, queue) { > + for_each_active_cmd(ipr_cmd, hrrq) { > if (match(ipr_cmd, device)) { > ipr_cmd->eh_comp = NULL; > wait++; > @@ -5193,7 +5192,7 @@ static int ipr_device_reset(struct ipr_i > > ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); > ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > if (ipr_is_gata(res) && res->sata_port && ioasc != > IPR_IOASC_IOA_WAS_RESET) { > if (ipr_cmd->ioa_cfg->sis64) > memcpy(&res->sata_port->ioasa, > &ipr_cmd->s.ioasa64.u.gata, > @@ -5294,7 +5293,7 @@ static int __ipr_eh_dev_reset(struct scs > > for_each_hrrq(hrrq, ioa_cfg) { > spin_lock(&hrrq->_lock); > - list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) { > + for_each_active_cmd(ipr_cmd, hrrq) { > if (ipr_cmd->ioarcb.res_handle == res->res_handle) { > if (ipr_cmd->scsi_cmd) > ipr_cmd->done = ipr_scsi_eh_done; > @@ -5362,7 +5361,7 @@ static void ipr_bus_reset_done(struct ip > else > ipr_cmd->sibling->done(ipr_cmd->sibling); > > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > LEAVE; > } > > @@ -5451,7 +5450,7 @@ static int ipr_cancel_op(struct scsi_cmn > > for_each_hrrq(hrrq, ioa_cfg) { > spin_lock(&hrrq->_lock); > - list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) { > + for_each_active_cmd(ipr_cmd, hrrq) { > if (ipr_cmd->scsi_cmd == scsi_cmd) { > ipr_cmd->done = ipr_scsi_eh_done; > op_found = 1; > @@ -5485,7 +5484,7 @@ static int ipr_cancel_op(struct scsi_cmn > ipr_trace; > } > > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > if (!ipr_is_naca_model(res)) > res->needs_sync_complete = 1; > > @@ -5634,7 +5633,6 @@ static irqreturn_t ipr_handle_other_inte > /* clear stage change */ > writel(IPR_PCII_IPL_STAGE_CHANGE, > ioa_cfg->regs.clr_interrupt_reg); > int_reg = > readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; > - list_del(&ioa_cfg->reset_cmd->queue); > del_timer(&ioa_cfg->reset_cmd->timer); > ipr_reset_ioa_job(ioa_cfg->reset_cmd); > return IRQ_HANDLED; > @@ -5649,7 +5647,6 @@ static irqreturn_t ipr_handle_other_inte > writel(IPR_PCII_IOA_TRANS_TO_OPER, > ioa_cfg->regs.set_interrupt_mask_reg); > int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); > > - list_del(&ioa_cfg->reset_cmd->queue); > del_timer(&ioa_cfg->reset_cmd->timer); > ipr_reset_ioa_job(ioa_cfg->reset_cmd); > } else if ((int_reg & IPR_PCII_HRRQ_UPDATED) == int_reg) { > @@ -5731,9 +5728,11 @@ static int ipr_process_hrrq(struct ipr_h > ipr_cmd = ioa_cfg->ipr_cmnd_list[cmd_index]; > ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); > > - ipr_trc_hook(ipr_cmd, IPR_TRACE_FINISH, ioasc); > - > - list_move_tail(&ipr_cmd->queue, doneq); > + if (!ipr_cmnd_complete(ipr_cmd)) { > + ipr_trc_hook(ipr_cmd, IPR_TRACE_FINISH, ioasc); > + list_add_tail(&ipr_cmd->queue, doneq); > + num_hrrq++; > + } > > if (hrr_queue->hrrq_curr < hrr_queue->hrrq_end) { > hrr_queue->hrrq_curr++; > @@ -5741,7 +5740,7 @@ static int ipr_process_hrrq(struct ipr_h > hrr_queue->hrrq_curr = hrr_queue->hrrq_start; > hrr_queue->toggle_bit ^= 1u; > } > - num_hrrq++; > + > if (budget > 0 && num_hrrq >= budget) > break; > } > @@ -6039,7 +6038,7 @@ static void ipr_erp_done(struct ipr_cmnd > res->in_erp = 0; > } > scsi_dma_unmap(ipr_cmd->scsi_cmd); > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > scsi_cmd->scsi_done(scsi_cmd); > } > > @@ -6056,6 +6055,7 @@ static void ipr_reinit_ipr_cmnd_for_erp( > struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa; > dma_addr_t dma_addr = ipr_cmd->dma_addr; > > + ipr_cmnd_clear_complete(ipr_cmd); > memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); > ioarcb->data_transfer_length = 0; > ioarcb->read_data_transfer_length = 0; > @@ -6430,7 +6430,7 @@ static void ipr_erp_start(struct ipr_ioa > } > > scsi_dma_unmap(ipr_cmd->scsi_cmd); > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > scsi_cmd->scsi_done(scsi_cmd); > } > > @@ -6455,9 +6455,8 @@ static void ipr_scsi_done(struct ipr_cmn > > if (likely(IPR_IOASC_SENSE_KEY(ioasc) == 0)) { > scsi_dma_unmap(scsi_cmd); > - > spin_lock_irqsave(ipr_cmd->hrrq->lock, lock_flags); > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > scsi_cmd->scsi_done(scsi_cmd); > spin_unlock_irqrestore(ipr_cmd->hrrq->lock, lock_flags); > } else { > @@ -6514,32 +6513,9 @@ static int ipr_queuecommand(struct Scsi_ > > hrrq = &ioa_cfg->hrrq[hrrq_id]; > > - spin_lock_irqsave(hrrq->lock, hrrq_flags); > - /* > - * We are currently blocking all devices due to a host reset > - * We have told the host to stop giving us new requests, but > - * ERP ops don't count. FIXME > - */ > - if (unlikely(!hrrq->allow_cmds && !hrrq->ioa_is_dead && > !hrrq->removing_ioa)) { > - spin_unlock_irqrestore(hrrq->lock, hrrq_flags); > - return SCSI_MLQUEUE_HOST_BUSY; > - } > - > - /* > - * FIXME - Create scsi_set_host_offline interface > - * and the ioa_is_dead check can be removed > - */ > - if (unlikely(hrrq->ioa_is_dead || hrrq->removing_ioa || !res)) { > - spin_unlock_irqrestore(hrrq->lock, hrrq_flags); > - goto err_nodev; > - } > - > ipr_cmd = __ipr_get_free_ipr_cmnd(hrrq); > - if (ipr_cmd == NULL) { > - spin_unlock_irqrestore(hrrq->lock, hrrq_flags); > + if (ipr_cmd == NULL) > return SCSI_MLQUEUE_HOST_BUSY; > - } > - spin_unlock_irqrestore(hrrq->lock, hrrq_flags); > > ipr_init_ipr_cmnd(ipr_cmd, ipr_scsi_done); > ioarcb = &ipr_cmd->ioarcb; > @@ -6585,16 +6561,16 @@ static int ipr_queuecommand(struct Scsi_ > rc = ipr_build_ioadl(ioa_cfg, ipr_cmd); > > spin_lock_irqsave(hrrq->lock, hrrq_flags); > - if (unlikely(rc || (!hrrq->allow_cmds && !hrrq->ioa_is_dead))) { > - list_add_tail(&ipr_cmd->queue, &hrrq->hrrq_free_q); > + if (unlikely(rc || (!hrrq->allow_cmds && !hrrq->ioa_is_dead && > !hrrq->removing_ioa))) { > + ipr_free_cmd(ipr_cmd); > spin_unlock_irqrestore(hrrq->lock, hrrq_flags); > if (!rc) > scsi_dma_unmap(scsi_cmd); > return SCSI_MLQUEUE_HOST_BUSY; > } > > - if (unlikely(hrrq->ioa_is_dead)) { > - list_add_tail(&ipr_cmd->queue, &hrrq->hrrq_free_q); > + if (unlikely(hrrq->ioa_is_dead || hrrq->removing_ioa)) { > + ipr_free_cmd(ipr_cmd); > spin_unlock_irqrestore(hrrq->lock, hrrq_flags); > scsi_dma_unmap(scsi_cmd); > goto err_nodev; > @@ -6605,7 +6581,6 @@ static int ipr_queuecommand(struct Scsi_ > ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_SYNC_COMPLETE; > res->needs_sync_complete = 0; > } > - list_add_tail(&ipr_cmd->queue, &hrrq->hrrq_pending_q); > ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res)); > ipr_send_command(ipr_cmd); > spin_unlock_irqrestore(hrrq->lock, hrrq_flags); > @@ -6721,7 +6696,7 @@ static void ipr_ata_post_internal(struct > > for_each_hrrq(hrrq, ioa_cfg) { > spin_lock(&hrrq->_lock); > - list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) { > + for_each_active_cmd(ipr_cmd, hrrq) { > if (ipr_cmd->qc == qc) > found++; > } > @@ -6794,7 +6769,7 @@ static void ipr_sata_done(struct ipr_cmn > qc->err_mask |= __ac_err_mask(sata_port->ioasa.status); > else > qc->err_mask |= ac_err_mask(sata_port->ioasa.status); > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > spin_unlock_irqrestore(ipr_cmd->hrrq->lock, flags); > ata_qc_complete(qc); > } > @@ -6960,7 +6935,7 @@ static unsigned int ipr_qc_issue(struct > spin_lock(&ipr_cmd->hrrq->_lock); > if (unlikely(!ipr_cmd->hrrq->allow_cmds || > ipr_cmd->hrrq->ioa_is_dead)) { > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > spin_unlock(&ipr_cmd->hrrq->_lock); > return AC_ERR_SYSTEM; > } > @@ -6977,7 +6952,6 @@ static unsigned int ipr_qc_issue(struct > memset(regs, 0, sizeof(*regs)); > ioarcb->add_cmd_parms_len = cpu_to_be16(sizeof(*regs)); > > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_pending_q); > ipr_cmd->qc = qc; > ipr_cmd->done = ipr_sata_done; > ipr_cmd->ioarcb.res_handle = res->res_handle; > @@ -7157,7 +7131,7 @@ static int ipr_ioa_bringdown_done(struct > ipr_send_back_failed_ops(ioa_cfg); > spin_lock_irq(ioa_cfg->host->host_lock); > > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > wake_up_all(&ioa_cfg->reset_wait_q); > LEAVE; > > @@ -7216,7 +7190,7 @@ static int ipr_ioa_reset_done(struct ipr > dev_info(&ioa_cfg->pdev->dev, "IOA initialized.\n"); > > ioa_cfg->reset_retries = 0; > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > wake_up_all(&ioa_cfg->reset_wait_q); > > spin_unlock_irq(ioa_cfg->host->host_lock); > @@ -7558,7 +7532,7 @@ static int ipr_reset_cmd_failed(struct i > ipr_cmd->ioarcb.cmd_pkt.cdb[0], ioasc); > > ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > return IPR_RC_JOB_RETURN; > } > > @@ -8065,8 +8039,7 @@ static int ipr_ioafp_page0_inquiry(struc > if (!ipr_testmode) { > ioa_cfg->reset_retries += IPR_NUM_RESET_RELOAD_RETRIES; > ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); > - list_add_tail(&ipr_cmd->queue, > - &ioa_cfg->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > return IPR_RC_JOB_RETURN; > } > } > @@ -8208,8 +8181,8 @@ static void ipr_reset_timer_done(struct > spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); > > if (ioa_cfg->reset_cmd == ipr_cmd) { > - list_del(&ipr_cmd->queue); > - ipr_cmd->done(ipr_cmd); > + if (!ipr_cmnd_complete(ipr_cmd)) > + ipr_cmd->done(ipr_cmd); > } > > spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); > @@ -8234,7 +8207,6 @@ static void ipr_reset_start_timer(struct > { > > ENTER; > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_pending_q); > ipr_cmd->done = ipr_reset_ioa_job; > > ipr_cmd->timer.data = (unsigned long) ipr_cmd; > @@ -8329,8 +8301,6 @@ static int ipr_reset_next_stage(struct i > ipr_cmd->done = ipr_reset_ioa_job; > add_timer(&ipr_cmd->timer); > > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_pending_q); > - > return IPR_RC_JOB_RETURN; > } > > @@ -8400,7 +8370,6 @@ static int ipr_reset_enable_ioa(struct i > ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout; > ipr_cmd->done = ipr_reset_ioa_job; > add_timer(&ipr_cmd->timer); > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_pending_q); > > LEAVE; > return IPR_RC_JOB_RETURN; > @@ -8931,10 +8900,10 @@ static int ipr_reset_cancel_hcam_done(st > > for_each_hrrq(hrrq, ioa_cfg) { > spin_lock(&hrrq->_lock); > - list_for_each_entry(loop_cmd, &hrrq->hrrq_pending_q, queue) { > + for_each_active_cmd(loop_cmd, hrrq) { > count++; > ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); > - list_add_tail(&ipr_cmd->queue, > &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > rc = IPR_RC_JOB_RETURN; > break; > } > @@ -8970,7 +8939,7 @@ static int ipr_reset_cancel_hcam(struct > > if (!hrrq->ioa_is_dead) { > if (!list_empty(&ioa_cfg->hostrcb_pending_q)) { > - list_for_each_entry(hcam_cmd, &hrrq->hrrq_pending_q, > queue) { > + for_each_active_cmd(hcam_cmd, hrrq) { > if (hcam_cmd->ioarcb.cmd_pkt.cdb[0] != > IPR_HOST_CONTROLLED_ASYNC) > continue; > > @@ -9137,8 +9106,7 @@ static void ipr_reset_ioa_job(struct ipr > * We are doing nested adapter resets and this is > * not the current reset job. > */ > - list_add_tail(&ipr_cmd->queue, > - &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > return; > } > > @@ -9275,7 +9243,6 @@ static int ipr_reset_freeze(struct ipr_c > spin_unlock(&ioa_cfg->hrrq[i]._lock); > } > wmb(); > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_pending_q); > ipr_cmd->done = ipr_reset_ioa_job; > return IPR_RC_JOB_RETURN; > } > @@ -9456,6 +9423,9 @@ static void ipr_free_cmd_blks(struct ipr > } > } > > + for (i = 0; i < ioa_cfg->hrrq_num; i++) > + kfree(ioa_cfg->hrrq[i].active_map); > + > if (ioa_cfg->ipr_cmd_pool) > dma_pool_destroy(ioa_cfg->ipr_cmd_pool); > > @@ -9613,6 +9583,8 @@ static int ipr_alloc_cmd_blks(struct ipr > ioa_cfg->hrrq[i].max_cmd_id = (entries_each_hrrq - 1); > } > ioa_cfg->hrrq[i].size = entries_each_hrrq; > + ioa_cfg->hrrq[i].active_map = > kcalloc(BITS_TO_LONGS(entries_each_hrrq), > + sizeof(unsigned long), > GFP_KERNEL); > } > > BUG_ON(ioa_cfg->hrrq_num == 0); > @@ -9664,7 +9636,6 @@ static int ipr_alloc_cmd_blks(struct ipr > > ipr_cmd->ioarcb.cmd_pkt.hrrq_id = hrrq_id; > ipr_cmd->hrrq = &ioa_cfg->hrrq[hrrq_id]; > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > if (i >= ioa_cfg->hrrq[hrrq_id].max_cmd_id) > hrrq_id++; > } > @@ -9911,8 +9882,6 @@ static void ipr_init_ioa_cfg(struct ipr_ > pci_set_drvdata(pdev, ioa_cfg); > > for (i = 0; i < ARRAY_SIZE(ioa_cfg->hrrq); i++) { > - INIT_LIST_HEAD(&ioa_cfg->hrrq[i].hrrq_free_q); > - INIT_LIST_HEAD(&ioa_cfg->hrrq[i].hrrq_pending_q); > INIT_LIST_HEAD(&ioa_cfg->hrrq[i].hrrq_error_q); > spin_lock_init(&ioa_cfg->hrrq[i]._lock); > if (i == 0) > @@ -10820,9 +10789,10 @@ static struct pci_driver ipr_driver = { > **/ > static void ipr_halt_done(struct ipr_cmnd *ipr_cmd) > { > - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); > + ipr_free_cmd(ipr_cmd); > } > > + > /** > * ipr_halt - Issue shutdown prepare to all adapters > * > _ > > > ------------------------------------------------------------------------------ > _______________________________________________ > Iprdd-devel mailing list > Iprdd-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/iprdd-devel > -- Gabriel Krisman Bertazi ------------------------------------------------------------------------------ _______________________________________________ Iprdd-devel mailing list Iprdd-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/iprdd-devel