diff options
author | Jens Axboe <axboe@kernel.dk> | 2018-11-29 19:36:41 -0500 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-11-30 16:48:04 -0500 |
commit | 5d2ee7122c73be6a3b6bfe90d237e8aed737cfaa (patch) | |
tree | ada2bd06a0523a6ab8a9eae652034e2b0cb7b996 /drivers/target | |
parent | ea86ea2cdced20057da4d2c32965c1219c238197 (diff) |
sbitmap: optimize wakeup check
Even if we have no waiters on any of the sbitmap_queue wait states, we
still have to loop every entry to check. We do this for every IO, so
the cost adds up.
Shift a bit of the cost to the slow path, when we actually have waiters.
Wrap prepare_to_wait_exclusive() and finish_wait(), so we can maintain
an internal count of how many are currently active. Then we can simply
check this count in sbq_wake_ptr() and not have to loop if we don't
have any sleepers.
Convert the two users of sbitmap with waiting, blk-mq-tag and iSCSI.
Reviewed-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/iscsi/iscsi_target_util.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 36b742932c72..86987da86dd6 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
@@ -150,24 +150,26 @@ void iscsit_free_r2ts_from_list(struct iscsi_cmd *cmd) | |||
150 | static int iscsit_wait_for_tag(struct se_session *se_sess, int state, int *cpup) | 150 | static int iscsit_wait_for_tag(struct se_session *se_sess, int state, int *cpup) |
151 | { | 151 | { |
152 | int tag = -1; | 152 | int tag = -1; |
153 | DEFINE_WAIT(wait); | 153 | DEFINE_SBQ_WAIT(wait); |
154 | struct sbq_wait_state *ws; | 154 | struct sbq_wait_state *ws; |
155 | struct sbitmap_queue *sbq; | ||
155 | 156 | ||
156 | if (state == TASK_RUNNING) | 157 | if (state == TASK_RUNNING) |
157 | return tag; | 158 | return tag; |
158 | 159 | ||
159 | ws = &se_sess->sess_tag_pool.ws[0]; | 160 | sbq = &se_sess->sess_tag_pool; |
161 | ws = &sbq->ws[0]; | ||
160 | for (;;) { | 162 | for (;;) { |
161 | prepare_to_wait_exclusive(&ws->wait, &wait, state); | 163 | sbitmap_prepare_to_wait(sbq, ws, &wait, state); |
162 | if (signal_pending_state(state, current)) | 164 | if (signal_pending_state(state, current)) |
163 | break; | 165 | break; |
164 | tag = sbitmap_queue_get(&se_sess->sess_tag_pool, cpup); | 166 | tag = sbitmap_queue_get(sbq, cpup); |
165 | if (tag >= 0) | 167 | if (tag >= 0) |
166 | break; | 168 | break; |
167 | schedule(); | 169 | schedule(); |
168 | } | 170 | } |
169 | 171 | ||
170 | finish_wait(&ws->wait, &wait); | 172 | sbitmap_finish_wait(sbq, ws, &wait); |
171 | return tag; | 173 | return tag; |
172 | } | 174 | } |
173 | 175 | ||