Re: [PATCH 1/2] Convert target drivers to use sbitmap
On Tue, Jun 12, 2018 at 03:22:42PM +, Bart Van Assche wrote: > On Tue, 2018-05-15 at 09:00 -0700, Matthew Wilcox wrote: > > diff --git a/drivers/scsi/qla2xxx/qla_target.c > > b/drivers/scsi/qla2xxx/qla_target.c > > index 025dc2d3f3de..cdf671c2af61 100644 > > --- a/drivers/scsi/qla2xxx/qla_target.c > > +++ b/drivers/scsi/qla2xxx/qla_target.c > > @@ -3719,7 +3719,8 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd) > > return; > > } > > cmd->jiffies_at_free = get_jiffies_64(); > > - percpu_ida_free(>se_sess->sess_tag_pool, cmd->se_cmd.map_tag); > > + sbitmap_queue_clear(>se_sess->sess_tag_pool, cmd->se_cmd.map_tag, > > + cmd->se_cmd.map_cpu); > > } > > EXPORT_SYMBOL(qlt_free_cmd); > > Please introduce functions in the target core for allocating and freeing a tag > instead of spreading the knowledge of how to allocate and free tags over all > target drivers. I can't without doing an unreasonably large amount of work on drivers that I have no way to test. Some of the drivers have the se_cmd already; some of them don't. I'd be happy to introduce a common function for freeing a tag. > > +int iscsit_wait_for_tag(struct se_session *se_sess, int state, int *cpup) > > +{ > > + int tag = -1; > > + DEFINE_WAIT(wait); > > + struct sbq_wait_state *ws; > > + > > + if (state == TASK_RUNNING) > > + return tag; > > + > > + ws = _sess->sess_tag_pool.ws[0]; > > + for (;;) { > > + prepare_to_wait_exclusive(>wait, , state); > > + if (signal_pending_state(state, current)) > > + break; > > This looks weird to me. Shouldn't target code ignore signals instead of > causing > tag allocation to fail if a signal is received? It's what the current code did: - if (signal_pending_state(state, current)) { - tag = -ERESTARTSYS; - break; - } and the current callers literally indicate that they want signals: drivers/infiniband/ulp/isert/ib_isert.c:cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE); drivers/target/iscsi/iscsi_target.c:cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE); (etc)
Re: [PATCH 1/2] Convert target drivers to use sbitmap
On Tue, Jun 12, 2018 at 03:22:42PM +, Bart Van Assche wrote: > On Tue, 2018-05-15 at 09:00 -0700, Matthew Wilcox wrote: > > diff --git a/drivers/scsi/qla2xxx/qla_target.c > > b/drivers/scsi/qla2xxx/qla_target.c > > index 025dc2d3f3de..cdf671c2af61 100644 > > --- a/drivers/scsi/qla2xxx/qla_target.c > > +++ b/drivers/scsi/qla2xxx/qla_target.c > > @@ -3719,7 +3719,8 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd) > > return; > > } > > cmd->jiffies_at_free = get_jiffies_64(); > > - percpu_ida_free(>se_sess->sess_tag_pool, cmd->se_cmd.map_tag); > > + sbitmap_queue_clear(>se_sess->sess_tag_pool, cmd->se_cmd.map_tag, > > + cmd->se_cmd.map_cpu); > > } > > EXPORT_SYMBOL(qlt_free_cmd); > > Please introduce functions in the target core for allocating and freeing a tag > instead of spreading the knowledge of how to allocate and free tags over all > target drivers. I can't without doing an unreasonably large amount of work on drivers that I have no way to test. Some of the drivers have the se_cmd already; some of them don't. I'd be happy to introduce a common function for freeing a tag. > > +int iscsit_wait_for_tag(struct se_session *se_sess, int state, int *cpup) > > +{ > > + int tag = -1; > > + DEFINE_WAIT(wait); > > + struct sbq_wait_state *ws; > > + > > + if (state == TASK_RUNNING) > > + return tag; > > + > > + ws = _sess->sess_tag_pool.ws[0]; > > + for (;;) { > > + prepare_to_wait_exclusive(>wait, , state); > > + if (signal_pending_state(state, current)) > > + break; > > This looks weird to me. Shouldn't target code ignore signals instead of > causing > tag allocation to fail if a signal is received? It's what the current code did: - if (signal_pending_state(state, current)) { - tag = -ERESTARTSYS; - break; - } and the current callers literally indicate that they want signals: drivers/infiniband/ulp/isert/ib_isert.c:cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE); drivers/target/iscsi/iscsi_target.c:cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE); (etc)
Re: [PATCH 1/2] Convert target drivers to use sbitmap
Hi Matthew, I love your patch! Perhaps something to improve: [auto build test WARNING on linus/master] [also build test WARNING on v4.17-rc5 next-20180516] [cannot apply to target/master] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Matthew-Wilcox/Use-sbitmap-instead-of-percpu_ida/20180516-143658 reproduce: # apt-get install sparse make ARCH=x86_64 allmodconfig make C=1 CF=-D__CHECK_ENDIAN__ sparse warnings: (new ones prefixed by >>) >> drivers/target/iscsi/iscsi_target_util.c:150:5: sparse: symbol >> 'iscsit_wait_for_tag' was not declared. Should it be static? drivers/target/iscsi/iscsi_target_util.c:1174:31: sparse: expression using sizeof(void) drivers/target/iscsi/iscsi_target_util.c:1174:31: sparse: expression using sizeof(void) Please review and possibly fold the followup patch. --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Re: [PATCH 1/2] Convert target drivers to use sbitmap
Hi Matthew, I love your patch! Perhaps something to improve: [auto build test WARNING on linus/master] [also build test WARNING on v4.17-rc5 next-20180516] [cannot apply to target/master] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Matthew-Wilcox/Use-sbitmap-instead-of-percpu_ida/20180516-143658 reproduce: # apt-get install sparse make ARCH=x86_64 allmodconfig make C=1 CF=-D__CHECK_ENDIAN__ sparse warnings: (new ones prefixed by >>) >> drivers/target/iscsi/iscsi_target_util.c:150:5: sparse: symbol >> 'iscsit_wait_for_tag' was not declared. Should it be static? drivers/target/iscsi/iscsi_target_util.c:1174:31: sparse: expression using sizeof(void) drivers/target/iscsi/iscsi_target_util.c:1174:31: sparse: expression using sizeof(void) Please review and possibly fold the followup patch. --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Re: [PATCH 1/2] Convert target drivers to use sbitmap
Hi, Matthew Wilcoxwrites: > From: Matthew Wilcox > > The sbitmap and the percpu_ida perform essentially the same task, > allocating tags for commands. Since the sbitmap is more used than > the percpu_ida, convert the percpu_ida users to the sbitmap API. > > Signed-off-by: Matthew Wilcox > --- [...] > drivers/usb/gadget/function/f_tcm.c | 8 +++--- for drivers/usb/gadget/function/f_tcm.c Acked-by: Felipe Balbi -- balbi signature.asc Description: PGP signature
Re: [PATCH 1/2] Convert target drivers to use sbitmap
Hi, Matthew Wilcox writes: > From: Matthew Wilcox > > The sbitmap and the percpu_ida perform essentially the same task, > allocating tags for commands. Since the sbitmap is more used than > the percpu_ida, convert the percpu_ida users to the sbitmap API. > > Signed-off-by: Matthew Wilcox > --- [...] > drivers/usb/gadget/function/f_tcm.c | 8 +++--- for drivers/usb/gadget/function/f_tcm.c Acked-by: Felipe Balbi -- balbi signature.asc Description: PGP signature
Re: [PATCH 1/2] Convert target drivers to use sbitmap
On 5/15/18 10:11 AM, Jens Axboe wrote: > On 5/15/18 10:00 AM, Matthew Wilcox wrote: >> From: Matthew Wilcox>> >> The sbitmap and the percpu_ida perform essentially the same task, >> allocating tags for commands. Since the sbitmap is more used than >> the percpu_ida, convert the percpu_ida users to the sbitmap API. > > It should also be the same performance as percpu_ida in light use, and > performs much better at > 50% utilization of the tag space. I think > that's better justification than "more used than". Had to search long and hard for the perf numbers I did for percpu_ida on higher utilization, but here it is: https://lkml.org/lkml/2014/4/22/553 -- Jens Axboe
Re: [PATCH 1/2] Convert target drivers to use sbitmap
On 5/15/18 10:11 AM, Jens Axboe wrote: > On 5/15/18 10:00 AM, Matthew Wilcox wrote: >> From: Matthew Wilcox >> >> The sbitmap and the percpu_ida perform essentially the same task, >> allocating tags for commands. Since the sbitmap is more used than >> the percpu_ida, convert the percpu_ida users to the sbitmap API. > > It should also be the same performance as percpu_ida in light use, and > performs much better at > 50% utilization of the tag space. I think > that's better justification than "more used than". Had to search long and hard for the perf numbers I did for percpu_ida on higher utilization, but here it is: https://lkml.org/lkml/2014/4/22/553 -- Jens Axboe
Re: [PATCH 1/2] Convert target drivers to use sbitmap
On 5/15/18 10:00 AM, Matthew Wilcox wrote: > From: Matthew Wilcox> > The sbitmap and the percpu_ida perform essentially the same task, > allocating tags for commands. Since the sbitmap is more used than > the percpu_ida, convert the percpu_ida users to the sbitmap API. It should also be the same performance as percpu_ida in light use, and performs much better at > 50% utilization of the tag space. I think that's better justification than "more used than". > diff --git a/drivers/target/iscsi/iscsi_target_util.c > b/drivers/target/iscsi/iscsi_target_util.c > index 4435bf374d2d..28bcffae609f 100644 > --- a/drivers/target/iscsi/iscsi_target_util.c > +++ b/drivers/target/iscsi/iscsi_target_util.c > @@ -17,7 +17,7 @@ > > **/ > > #include > -#include > +#include > #include /* ipv6_addr_equal() */ > #include > #include > @@ -147,6 +147,28 @@ void iscsit_free_r2ts_from_list(struct iscsi_cmd *cmd) > spin_unlock_bh(>r2t_lock); > } > > +int iscsit_wait_for_tag(struct se_session *se_sess, int state, int *cpup) > +{ > + int tag = -1; > + DEFINE_WAIT(wait); > + struct sbq_wait_state *ws; > + > + if (state == TASK_RUNNING) > + return tag; > + > + ws = _sess->sess_tag_pool.ws[0]; > + for (;;) { > + prepare_to_wait_exclusive(>wait, , state); > + if (signal_pending_state(state, current)) > + break; > + schedule(); > + tag = sbitmap_queue_get(_sess->sess_tag_pool, cpup); > + } > + > + finish_wait(>wait, ); > + return tag; > +} Seems like that should be: ws = _sess->sess_tag_pool.ws[0]; for (;;) { prepare_to_wait_exclusive(>wait, , state); if (signal_pending_state(state, current)) break; tag = sbitmap_queue_get(_sess->sess_tag_pool, cpup); if (tag != -1) break; schedule(); } finish_wait(>wait, ); return tag; > /* > * May be called from software interrupt (timer) context for allocating > * iSCSI NopINs. > @@ -155,9 +177,11 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn > *conn, int state) > { > struct iscsi_cmd *cmd; > struct se_session *se_sess = conn->sess->se_sess; > - int size, tag; > + int size, tag, cpu; > > - tag = percpu_ida_alloc(_sess->sess_tag_pool, state); > + tag = sbitmap_queue_get(_sess->sess_tag_pool, ); > + if (tag < 0) > + tag = iscsit_wait_for_tag(se_sess, state, ); > if (tag < 0) > return NULL; Might make sense to just roll the whole thing into iscsi_get_tag(), that would be cleaner. sbitmap should provide a helper for that, but we can do that cleanup later. That would encapsulate things like the per-cpu caching hint too, for instance. Rest looks fine to me. -- Jens Axboe
Re: [PATCH 1/2] Convert target drivers to use sbitmap
On 5/15/18 10:00 AM, Matthew Wilcox wrote: > From: Matthew Wilcox > > The sbitmap and the percpu_ida perform essentially the same task, > allocating tags for commands. Since the sbitmap is more used than > the percpu_ida, convert the percpu_ida users to the sbitmap API. It should also be the same performance as percpu_ida in light use, and performs much better at > 50% utilization of the tag space. I think that's better justification than "more used than". > diff --git a/drivers/target/iscsi/iscsi_target_util.c > b/drivers/target/iscsi/iscsi_target_util.c > index 4435bf374d2d..28bcffae609f 100644 > --- a/drivers/target/iscsi/iscsi_target_util.c > +++ b/drivers/target/iscsi/iscsi_target_util.c > @@ -17,7 +17,7 @@ > > **/ > > #include > -#include > +#include > #include /* ipv6_addr_equal() */ > #include > #include > @@ -147,6 +147,28 @@ void iscsit_free_r2ts_from_list(struct iscsi_cmd *cmd) > spin_unlock_bh(>r2t_lock); > } > > +int iscsit_wait_for_tag(struct se_session *se_sess, int state, int *cpup) > +{ > + int tag = -1; > + DEFINE_WAIT(wait); > + struct sbq_wait_state *ws; > + > + if (state == TASK_RUNNING) > + return tag; > + > + ws = _sess->sess_tag_pool.ws[0]; > + for (;;) { > + prepare_to_wait_exclusive(>wait, , state); > + if (signal_pending_state(state, current)) > + break; > + schedule(); > + tag = sbitmap_queue_get(_sess->sess_tag_pool, cpup); > + } > + > + finish_wait(>wait, ); > + return tag; > +} Seems like that should be: ws = _sess->sess_tag_pool.ws[0]; for (;;) { prepare_to_wait_exclusive(>wait, , state); if (signal_pending_state(state, current)) break; tag = sbitmap_queue_get(_sess->sess_tag_pool, cpup); if (tag != -1) break; schedule(); } finish_wait(>wait, ); return tag; > /* > * May be called from software interrupt (timer) context for allocating > * iSCSI NopINs. > @@ -155,9 +177,11 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn > *conn, int state) > { > struct iscsi_cmd *cmd; > struct se_session *se_sess = conn->sess->se_sess; > - int size, tag; > + int size, tag, cpu; > > - tag = percpu_ida_alloc(_sess->sess_tag_pool, state); > + tag = sbitmap_queue_get(_sess->sess_tag_pool, ); > + if (tag < 0) > + tag = iscsit_wait_for_tag(se_sess, state, ); > if (tag < 0) > return NULL; Might make sense to just roll the whole thing into iscsi_get_tag(), that would be cleaner. sbitmap should provide a helper for that, but we can do that cleanup later. That would encapsulate things like the per-cpu caching hint too, for instance. Rest looks fine to me. -- Jens Axboe
[PATCH 1/2] Convert target drivers to use sbitmap
From: Matthew WilcoxThe sbitmap and the percpu_ida perform essentially the same task, allocating tags for commands. Since the sbitmap is more used than the percpu_ida, convert the percpu_ida users to the sbitmap API. Signed-off-by: Matthew Wilcox --- drivers/scsi/qla2xxx/qla_target.c| 16 ++- drivers/target/iscsi/iscsi_target_util.c | 34 +--- drivers/target/sbp/sbp_target.c | 8 +++--- drivers/target/target_core_transport.c | 5 ++-- drivers/target/tcm_fc/tfc_cmd.c | 11 drivers/usb/gadget/function/f_tcm.c | 8 +++--- drivers/vhost/scsi.c | 9 --- drivers/xen/xen-scsiback.c | 8 +++--- include/target/iscsi/iscsi_target_core.h | 1 + include/target/target_core_base.h| 5 ++-- 10 files changed, 73 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 025dc2d3f3de..cdf671c2af61 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -3719,7 +3719,8 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd) return; } cmd->jiffies_at_free = get_jiffies_64(); - percpu_ida_free(>se_sess->sess_tag_pool, cmd->se_cmd.map_tag); + sbitmap_queue_clear(>se_sess->sess_tag_pool, cmd->se_cmd.map_tag, + cmd->se_cmd.map_cpu); } EXPORT_SYMBOL(qlt_free_cmd); @@ -4084,7 +4085,8 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd) qlt_send_term_exchange(qpair, NULL, >atio, 1, 0); qlt_decr_num_pend_cmds(vha); - percpu_ida_free(>se_sess->sess_tag_pool, cmd->se_cmd.map_tag); + sbitmap_queue_clear(>se_sess->sess_tag_pool, cmd->se_cmd.map_tag, + cmd->se_cmd.map_cpu); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); spin_lock_irqsave(>tgt.sess_lock, flags); @@ -4215,9 +4217,9 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha, { struct se_session *se_sess = sess->se_sess; struct qla_tgt_cmd *cmd; - int tag; + int tag, cpu; - tag = percpu_ida_alloc(_sess->sess_tag_pool, TASK_RUNNING); + tag = sbitmap_queue_get(_sess->sess_tag_pool, ); if (tag < 0) return NULL; @@ -4230,6 +4232,7 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha, qlt_incr_num_pend_cmds(vha); cmd->vha = vha; cmd->se_cmd.map_tag = tag; + cmd->se_cmd.map_cpu = cpu; cmd->sess = sess; cmd->loop_id = sess->loop_id; cmd->conf_compl_supported = sess->conf_compl_supported; @@ -5212,7 +5215,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, struct fc_port *sess; struct se_session *se_sess; struct qla_tgt_cmd *cmd; - int tag; + int tag, cpu; unsigned long flags; if (unlikely(tgt->tgt_stop)) { @@ -5244,7 +5247,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, se_sess = sess->se_sess; - tag = percpu_ida_alloc(_sess->sess_tag_pool, TASK_RUNNING); + tag = sbitmap_queue_get(_sess->sess_tag_pool, ); if (tag < 0) return; @@ -5275,6 +5278,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, cmd->reset_count = ha->base_qpair->chip_reset; cmd->q_full = 1; cmd->qpair = ha->base_qpair; + cmd->se_cmd.map_cpu = cpu; if (qfull) { cmd->q_full = 1; diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 4435bf374d2d..28bcffae609f 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -17,7 +17,7 @@ **/ #include -#include +#include #include /* ipv6_addr_equal() */ #include #include @@ -147,6 +147,28 @@ void iscsit_free_r2ts_from_list(struct iscsi_cmd *cmd) spin_unlock_bh(>r2t_lock); } +int iscsit_wait_for_tag(struct se_session *se_sess, int state, int *cpup) +{ + int tag = -1; + DEFINE_WAIT(wait); + struct sbq_wait_state *ws; + + if (state == TASK_RUNNING) + return tag; + + ws = _sess->sess_tag_pool.ws[0]; + for (;;) { + prepare_to_wait_exclusive(>wait, , state); + if (signal_pending_state(state, current)) + break; + schedule(); + tag = sbitmap_queue_get(_sess->sess_tag_pool, cpup); + } + + finish_wait(>wait, ); + return tag; +} + /* * May be called from software interrupt (timer) context for allocating * iSCSI NopINs. @@ -155,9 +177,11 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, int state) { struct iscsi_cmd *cmd; struct se_session *se_sess = conn->sess->se_sess; - int size, tag; + int
[PATCH 1/2] Convert target drivers to use sbitmap
From: Matthew Wilcox The sbitmap and the percpu_ida perform essentially the same task, allocating tags for commands. Since the sbitmap is more used than the percpu_ida, convert the percpu_ida users to the sbitmap API. Signed-off-by: Matthew Wilcox --- drivers/scsi/qla2xxx/qla_target.c| 16 ++- drivers/target/iscsi/iscsi_target_util.c | 34 +--- drivers/target/sbp/sbp_target.c | 8 +++--- drivers/target/target_core_transport.c | 5 ++-- drivers/target/tcm_fc/tfc_cmd.c | 11 drivers/usb/gadget/function/f_tcm.c | 8 +++--- drivers/vhost/scsi.c | 9 --- drivers/xen/xen-scsiback.c | 8 +++--- include/target/iscsi/iscsi_target_core.h | 1 + include/target/target_core_base.h| 5 ++-- 10 files changed, 73 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 025dc2d3f3de..cdf671c2af61 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -3719,7 +3719,8 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd) return; } cmd->jiffies_at_free = get_jiffies_64(); - percpu_ida_free(>se_sess->sess_tag_pool, cmd->se_cmd.map_tag); + sbitmap_queue_clear(>se_sess->sess_tag_pool, cmd->se_cmd.map_tag, + cmd->se_cmd.map_cpu); } EXPORT_SYMBOL(qlt_free_cmd); @@ -4084,7 +4085,8 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd) qlt_send_term_exchange(qpair, NULL, >atio, 1, 0); qlt_decr_num_pend_cmds(vha); - percpu_ida_free(>se_sess->sess_tag_pool, cmd->se_cmd.map_tag); + sbitmap_queue_clear(>se_sess->sess_tag_pool, cmd->se_cmd.map_tag, + cmd->se_cmd.map_cpu); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); spin_lock_irqsave(>tgt.sess_lock, flags); @@ -4215,9 +4217,9 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha, { struct se_session *se_sess = sess->se_sess; struct qla_tgt_cmd *cmd; - int tag; + int tag, cpu; - tag = percpu_ida_alloc(_sess->sess_tag_pool, TASK_RUNNING); + tag = sbitmap_queue_get(_sess->sess_tag_pool, ); if (tag < 0) return NULL; @@ -4230,6 +4232,7 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha, qlt_incr_num_pend_cmds(vha); cmd->vha = vha; cmd->se_cmd.map_tag = tag; + cmd->se_cmd.map_cpu = cpu; cmd->sess = sess; cmd->loop_id = sess->loop_id; cmd->conf_compl_supported = sess->conf_compl_supported; @@ -5212,7 +5215,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, struct fc_port *sess; struct se_session *se_sess; struct qla_tgt_cmd *cmd; - int tag; + int tag, cpu; unsigned long flags; if (unlikely(tgt->tgt_stop)) { @@ -5244,7 +5247,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, se_sess = sess->se_sess; - tag = percpu_ida_alloc(_sess->sess_tag_pool, TASK_RUNNING); + tag = sbitmap_queue_get(_sess->sess_tag_pool, ); if (tag < 0) return; @@ -5275,6 +5278,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, cmd->reset_count = ha->base_qpair->chip_reset; cmd->q_full = 1; cmd->qpair = ha->base_qpair; + cmd->se_cmd.map_cpu = cpu; if (qfull) { cmd->q_full = 1; diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 4435bf374d2d..28bcffae609f 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -17,7 +17,7 @@ **/ #include -#include +#include #include /* ipv6_addr_equal() */ #include #include @@ -147,6 +147,28 @@ void iscsit_free_r2ts_from_list(struct iscsi_cmd *cmd) spin_unlock_bh(>r2t_lock); } +int iscsit_wait_for_tag(struct se_session *se_sess, int state, int *cpup) +{ + int tag = -1; + DEFINE_WAIT(wait); + struct sbq_wait_state *ws; + + if (state == TASK_RUNNING) + return tag; + + ws = _sess->sess_tag_pool.ws[0]; + for (;;) { + prepare_to_wait_exclusive(>wait, , state); + if (signal_pending_state(state, current)) + break; + schedule(); + tag = sbitmap_queue_get(_sess->sess_tag_pool, cpup); + } + + finish_wait(>wait, ); + return tag; +} + /* * May be called from software interrupt (timer) context for allocating * iSCSI NopINs. @@ -155,9 +177,11 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, int state) { struct iscsi_cmd *cmd; struct se_session *se_sess = conn->sess->se_sess; - int size, tag; + int size, tag, cpu; - tag =