Skip to content

Commit 4443f8e

Browse files
committed
Merge tag 'for-linus-20190412' of git://git.kernel.dk/linux-block
Pull block fixes from Jens Axboe: "Set of fixes that should go into this round. This pull is larger than I'd like at this time, but there's really no specific reason for that. Some are fixes for issues that went into this merge window, others are not. Anyway, this contains: - Hardware queue limiting for virtio-blk/scsi (Dongli) - Multi-page bvec fixes for lightnvm pblk - Multi-bio dio error fix (Jason) - Remove the cache hint from the io_uring tool side, since we didn't move forward with that (me) - Make io_uring SETUP_SQPOLL root restricted (me) - Fix leak of page in error handling for pc requests (Jérôme) - Fix BFQ regression introduced in this merge window (Paolo) - Fix break logic for bio segment iteration (Ming) - Fix NVMe cancel request error handling (Ming) - NVMe pull request with two fixes (Christoph): - fix the initial CSN for nvme-fc (James) - handle log page offsets properly in the target (Keith)" * tag 'for-linus-20190412' of git://git.kernel.dk/linux-block: block: fix the return errno for direct IO nvmet: fix discover log page when offsets are used nvme-fc: correct csn initialization and increments on error block: do not leak memory in bio_copy_user_iov() lightnvm: pblk: fix crash in pblk_end_partial_read due to multipage bvecs nvme: cancel request synchronously blk-mq: introduce blk_mq_complete_request_sync() scsi: virtio_scsi: limit number of hw queues by nr_cpu_ids virtio-blk: limit number of hw queues by nr_cpu_ids block, bfq: fix use after free in bfq_bfqq_expire io_uring: restrict IORING_SETUP_SQPOLL to root tools/io_uring: remove IOCQE_FLAG_CACHEHIT block: don't use for-inside-for in bio_for_each_segment_all
2 parents b60bc06 + a89afe5 commit 4443f8e

File tree

20 files changed

+174
-109
lines changed

20 files changed

+174
-109
lines changed

block/bfq-iosched.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2822,7 +2822,7 @@ static void bfq_dispatch_remove(struct request_queue *q, struct request *rq)
28222822
bfq_remove_request(q, rq);
28232823
}
28242824

2825-
static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
2825+
static bool __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
28262826
{
28272827
/*
28282828
* If this bfqq is shared between multiple processes, check
@@ -2855,9 +2855,11 @@ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
28552855
/*
28562856
* All in-service entities must have been properly deactivated
28572857
* or requeued before executing the next function, which
2858-
* resets all in-service entites as no more in service.
2858+
* resets all in-service entities as no more in service. This
2859+
* may cause bfqq to be freed. If this happens, the next
2860+
* function returns true.
28592861
*/
2860-
__bfq_bfqd_reset_in_service(bfqd);
2862+
return __bfq_bfqd_reset_in_service(bfqd);
28612863
}
28622864

28632865
/**
@@ -3262,7 +3264,6 @@ void bfq_bfqq_expire(struct bfq_data *bfqd,
32623264
bool slow;
32633265
unsigned long delta = 0;
32643266
struct bfq_entity *entity = &bfqq->entity;
3265-
int ref;
32663267

32673268
/*
32683269
* Check whether the process is slow (see bfq_bfqq_is_slow).
@@ -3347,10 +3348,8 @@ void bfq_bfqq_expire(struct bfq_data *bfqd,
33473348
* reason.
33483349
*/
33493350
__bfq_bfqq_recalc_budget(bfqd, bfqq, reason);
3350-
ref = bfqq->ref;
3351-
__bfq_bfqq_expire(bfqd, bfqq);
3352-
3353-
if (ref == 1) /* bfqq is gone, no more actions on it */
3351+
if (__bfq_bfqq_expire(bfqd, bfqq))
3352+
/* bfqq is gone, no more actions on it */
33543353
return;
33553354

33563355
bfqq->injected_service = 0;

block/bfq-iosched.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,7 @@ bool __bfq_deactivate_entity(struct bfq_entity *entity,
995995
bool ins_into_idle_tree);
996996
bool next_queue_may_preempt(struct bfq_data *bfqd);
997997
struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd);
998-
void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd);
998+
bool __bfq_bfqd_reset_in_service(struct bfq_data *bfqd);
999999
void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
10001000
bool ins_into_idle_tree, bool expiration);
10011001
void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq);

block/bfq-wf2q.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,7 +1605,8 @@ struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
16051605
return bfqq;
16061606
}
16071607

1608-
void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
1608+
/* returns true if the in-service queue gets freed */
1609+
bool __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
16091610
{
16101611
struct bfq_queue *in_serv_bfqq = bfqd->in_service_queue;
16111612
struct bfq_entity *in_serv_entity = &in_serv_bfqq->entity;
@@ -1629,8 +1630,20 @@ void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
16291630
* service tree either, then release the service reference to
16301631
* the queue it represents (taken with bfq_get_entity).
16311632
*/
1632-
if (!in_serv_entity->on_st)
1633+
if (!in_serv_entity->on_st) {
1634+
/*
1635+
* If no process is referencing in_serv_bfqq any
1636+
* longer, then the service reference may be the only
1637+
* reference to the queue. If this is the case, then
1638+
* bfqq gets freed here.
1639+
*/
1640+
int ref = in_serv_bfqq->ref;
16331641
bfq_put_queue(in_serv_bfqq);
1642+
if (ref == 1)
1643+
return true;
1644+
}
1645+
1646+
return false;
16341647
}
16351648

16361649
void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,

block/bio.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1298,8 +1298,11 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
12981298
}
12991299
}
13001300

1301-
if (bio_add_pc_page(q, bio, page, bytes, offset) < bytes)
1301+
if (bio_add_pc_page(q, bio, page, bytes, offset) < bytes) {
1302+
if (!map_data)
1303+
__free_page(page);
13021304
break;
1305+
}
13031306

13041307
len -= bytes;
13051308
offset = 0;

block/blk-mq.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,13 @@ bool blk_mq_complete_request(struct request *rq)
654654
}
655655
EXPORT_SYMBOL(blk_mq_complete_request);
656656

657+
void blk_mq_complete_request_sync(struct request *rq)
658+
{
659+
WRITE_ONCE(rq->state, MQ_RQ_COMPLETE);
660+
rq->q->mq_ops->complete(rq);
661+
}
662+
EXPORT_SYMBOL_GPL(blk_mq_complete_request_sync);
663+
657664
int blk_mq_request_started(struct request *rq)
658665
{
659666
return blk_mq_rq_state(rq) != MQ_RQ_IDLE;

drivers/block/virtio_blk.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,8 @@ static int init_vq(struct virtio_blk *vblk)
513513
if (err)
514514
num_vqs = 1;
515515

516+
num_vqs = min_t(unsigned int, nr_cpu_ids, num_vqs);
517+
516518
vblk->vqs = kmalloc_array(num_vqs, sizeof(*vblk->vqs), GFP_KERNEL);
517519
if (!vblk->vqs)
518520
return -ENOMEM;

drivers/lightnvm/pblk-read.c

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -231,14 +231,14 @@ static void pblk_end_partial_read(struct nvm_rq *rqd)
231231
struct pblk_sec_meta *meta;
232232
struct bio *new_bio = rqd->bio;
233233
struct bio *bio = pr_ctx->orig_bio;
234-
struct bio_vec src_bv, dst_bv;
235234
void *meta_list = rqd->meta_list;
236-
int bio_init_idx = pr_ctx->bio_init_idx;
237235
unsigned long *read_bitmap = pr_ctx->bitmap;
236+
struct bvec_iter orig_iter = BVEC_ITER_ALL_INIT;
237+
struct bvec_iter new_iter = BVEC_ITER_ALL_INIT;
238238
int nr_secs = pr_ctx->orig_nr_secs;
239239
int nr_holes = nr_secs - bitmap_weight(read_bitmap, nr_secs);
240240
void *src_p, *dst_p;
241-
int hole, i;
241+
int bit, i;
242242

243243
if (unlikely(nr_holes == 1)) {
244244
struct ppa_addr ppa;
@@ -257,33 +257,39 @@ static void pblk_end_partial_read(struct nvm_rq *rqd)
257257

258258
/* Fill the holes in the original bio */
259259
i = 0;
260-
hole = find_first_zero_bit(read_bitmap, nr_secs);
261-
do {
262-
struct pblk_line *line;
260+
for (bit = 0; bit < nr_secs; bit++) {
261+
if (!test_bit(bit, read_bitmap)) {
262+
struct bio_vec dst_bv, src_bv;
263+
struct pblk_line *line;
263264

264-
line = pblk_ppa_to_line(pblk, rqd->ppa_list[i]);
265-
kref_put(&line->ref, pblk_line_put);
265+
line = pblk_ppa_to_line(pblk, rqd->ppa_list[i]);
266+
kref_put(&line->ref, pblk_line_put);
266267

267-
meta = pblk_get_meta(pblk, meta_list, hole);
268-
meta->lba = cpu_to_le64(pr_ctx->lba_list_media[i]);
268+
meta = pblk_get_meta(pblk, meta_list, bit);
269+
meta->lba = cpu_to_le64(pr_ctx->lba_list_media[i]);
269270

270-
src_bv = new_bio->bi_io_vec[i++];
271-
dst_bv = bio->bi_io_vec[bio_init_idx + hole];
271+
dst_bv = bio_iter_iovec(bio, orig_iter);
272+
src_bv = bio_iter_iovec(new_bio, new_iter);
272273

273-
src_p = kmap_atomic(src_bv.bv_page);
274-
dst_p = kmap_atomic(dst_bv.bv_page);
274+
src_p = kmap_atomic(src_bv.bv_page);
275+
dst_p = kmap_atomic(dst_bv.bv_page);
275276

276-
memcpy(dst_p + dst_bv.bv_offset,
277-
src_p + src_bv.bv_offset,
278-
PBLK_EXPOSED_PAGE_SIZE);
277+
memcpy(dst_p + dst_bv.bv_offset,
278+
src_p + src_bv.bv_offset,
279+
PBLK_EXPOSED_PAGE_SIZE);
279280

280-
kunmap_atomic(src_p);
281-
kunmap_atomic(dst_p);
281+
kunmap_atomic(src_p);
282+
kunmap_atomic(dst_p);
282283

283-
mempool_free(src_bv.bv_page, &pblk->page_bio_pool);
284+
flush_dcache_page(dst_bv.bv_page);
285+
mempool_free(src_bv.bv_page, &pblk->page_bio_pool);
284286

285-
hole = find_next_zero_bit(read_bitmap, nr_secs, hole + 1);
286-
} while (hole < nr_secs);
287+
bio_advance_iter(new_bio, &new_iter,
288+
PBLK_EXPOSED_PAGE_SIZE);
289+
i++;
290+
}
291+
bio_advance_iter(bio, &orig_iter, PBLK_EXPOSED_PAGE_SIZE);
292+
}
287293

288294
bio_put(new_bio);
289295
kfree(pr_ctx);

drivers/nvme/host/core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ bool nvme_cancel_request(struct request *req, void *data, bool reserved)
288288
"Cancelling I/O %d", req->tag);
289289

290290
nvme_req(req)->status = NVME_SC_ABORT_REQ;
291-
blk_mq_complete_request(req);
291+
blk_mq_complete_request_sync(req);
292292
return true;
293293
}
294294
EXPORT_SYMBOL_GPL(nvme_cancel_request);

drivers/nvme/host/fc.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,7 +1845,7 @@ nvme_fc_init_queue(struct nvme_fc_ctrl *ctrl, int idx)
18451845
memset(queue, 0, sizeof(*queue));
18461846
queue->ctrl = ctrl;
18471847
queue->qnum = idx;
1848-
atomic_set(&queue->csn, 1);
1848+
atomic_set(&queue->csn, 0);
18491849
queue->dev = ctrl->dev;
18501850

18511851
if (idx > 0)
@@ -1887,7 +1887,7 @@ nvme_fc_free_queue(struct nvme_fc_queue *queue)
18871887
*/
18881888

18891889
queue->connection_id = 0;
1890-
atomic_set(&queue->csn, 1);
1890+
atomic_set(&queue->csn, 0);
18911891
}
18921892

18931893
static void
@@ -2183,7 +2183,6 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,
21832183
{
21842184
struct nvme_fc_cmd_iu *cmdiu = &op->cmd_iu;
21852185
struct nvme_command *sqe = &cmdiu->sqe;
2186-
u32 csn;
21872186
int ret, opstate;
21882187

21892188
/*
@@ -2198,8 +2197,6 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,
21982197

21992198
/* format the FC-NVME CMD IU and fcp_req */
22002199
cmdiu->connection_id = cpu_to_be64(queue->connection_id);
2201-
csn = atomic_inc_return(&queue->csn);
2202-
cmdiu->csn = cpu_to_be32(csn);
22032200
cmdiu->data_len = cpu_to_be32(data_len);
22042201
switch (io_dir) {
22052202
case NVMEFC_FCP_WRITE:
@@ -2257,11 +2254,24 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,
22572254
if (!(op->flags & FCOP_FLAGS_AEN))
22582255
blk_mq_start_request(op->rq);
22592256

2257+
cmdiu->csn = cpu_to_be32(atomic_inc_return(&queue->csn));
22602258
ret = ctrl->lport->ops->fcp_io(&ctrl->lport->localport,
22612259
&ctrl->rport->remoteport,
22622260
queue->lldd_handle, &op->fcp_req);
22632261

22642262
if (ret) {
2263+
/*
2264+
* If the lld fails to send the command is there an issue with
2265+
* the csn value? If the command that fails is the Connect,
2266+
* no - as the connection won't be live. If it is a command
2267+
* post-connect, it's possible a gap in csn may be created.
2268+
* Does this matter? As Linux initiators don't send fused
2269+
* commands, no. The gap would exist, but as there's nothing
2270+
* that depends on csn order to be delivered on the target
2271+
* side, it shouldn't hurt. It would be difficult for a
2272+
* target to even detect the csn gap as it has no idea when the
2273+
* cmd with the csn was supposed to arrive.
2274+
*/
22652275
opstate = atomic_xchg(&op->state, FCPOP_STATE_COMPLETE);
22662276
__nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate);
22672277

drivers/nvme/target/admin-cmd.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ u32 nvmet_get_log_page_len(struct nvme_command *cmd)
2424
return len;
2525
}
2626

27+
u64 nvmet_get_log_page_offset(struct nvme_command *cmd)
28+
{
29+
return le64_to_cpu(cmd->get_log_page.lpo);
30+
}
31+
2732
static void nvmet_execute_get_log_page_noop(struct nvmet_req *req)
2833
{
2934
nvmet_req_complete(req, nvmet_zero_sgl(req, 0, req->data_len));

0 commit comments

Comments
 (0)