We ran into an issue in production where reading an NVMe drive log randomly fails. The request is a big one, 1056K, and the application (nvme-cli) nicely aligns the buffer. This means the kernel will attempt to map the pages in for zero-copy DMA, but we ultimately fail adding enough pages to the request to satisfy the size requirement as we ran out of segments supported by the hardware. If we fail a user map that attempts to map pages in directly, retry with copy == true set. Signed-off-by: Jens Axboe <axboe@xxxxxxxxx> --- diff --git a/block/blk-map.c b/block/blk-map.c index db9373bd31ac..2dc5286baec6 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -131,6 +131,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, else if (queue_virt_boundary(q)) copy = queue_virt_boundary(q) & iov_iter_gap_alignment(iter); +retry: i = *iter; do { ret =__blk_rq_map_user_iov(rq, map_data, &i, gfp_mask, copy); @@ -148,6 +149,10 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, __blk_rq_unmap_user(bio); fail: rq->bio = NULL; + if (ret && !copy) { + copy = true; + goto retry; + } return ret; } EXPORT_SYMBOL(blk_rq_map_user_iov); -- Jens Axboe