Merge tag 'block-7.3-20260911' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux
Merge commit. Changes below are compared with the first parent: 42f961c4.
Changes
5 files changed · +49 −3
| File | Status | Add | Del | Content |
|---|---|---|---|---|
| drivers/block/sunvdc.c | modified | +25 | −1 | View file |
| drivers/block/ublk_drv.c | modified | +1 | −0 | View file |
| lib/iov_iter.c | modified | +16 | −2 | View file |
| tools/testing/selftests/ublk/Makefile | modified | +2 | −0 | View file |
| tools/testing/selftests/ublk/test_recover_03.sh | modified | +5 | −0 | View file |
drivers/block/sunvdc.c
View filediff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 020bd9f..2be8231 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -525,6 +525,23 @@ static int __send_request(struct request *req)
err = __vdc_tx_trigger(port);
if (err < 0) {
printk(KERN_ERR PFX "vdc_tx_trigger() failure, err=%d\n", err);
+ /*
+ * If the port was reset (-ENOTCONN), the dring and the
+ * LDC channel including all of its mappings are already
+ * torn down and reallocated - there is nothing to undo
+ * and @desc must not be touched.
+ *
+ * For any other failure the descriptor was never handed
+ * to the peer: unmap the cookies and free the descriptor
+ * again, so that a later retry of the request does not
+ * leak LDC map table entries.
+ */
+ if (err != -ENOTCONN) {
+ ldc_unmap(port->vio.lp, desc->cookies,
+ desc->ncookies);
+ desc->hdr.state = VIO_DESC_FREE;
+ rqe->req = NULL;
+ }
} else {
port->req_id++;
dr->prod = vio_dring_next(dr, dr->prod);
@@ -539,6 +556,7 @@ static blk_status_t vdc_queue_rq(struct blk_mq_hw_ctx *hctx,
struct vdc_port *port = hctx->queue->queuedata;
struct vio_dring_state *dr;
unsigned long flags;
+ int ret;
dr = &port->vio.drings[VIO_DRIVER_TX_RING];
@@ -560,7 +578,13 @@ static blk_status_t vdc_queue_rq(struct blk_mq_hw_ctx *hctx,
return BLK_STS_DEV_RESOURCE;
}
- if (__send_request(bd->rq) < 0) {
+ ret = __send_request(bd->rq);
+ if (ret == -EAGAIN) {
+ spin_unlock_irqrestore(&port->vio.lock, flags);
+ /* already spun for 10msec, defer 10msec and retry */
+ blk_mq_delay_kick_requeue_list(hctx->queue, 10);
+ return BLK_STS_DEV_RESOURCE;
+ } else if (ret < 0) {
spin_unlock_irqrestore(&port->vio.lock, flags);
return BLK_STS_IOERR;
}
drivers/block/ublk_drv.c
View filediff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index c387fb5..66eb55e 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -3030,6 +3030,7 @@ static void ublk_queue_reset_io_flags(struct ublk_queue *ubq)
ubq->canceling = false;
spin_unlock(&ubq->cancel_lock);
ubq->fail_io = false;
+ ubq->force_abort = false;
}
/* device can only be started after all IOs are ready */
lib/iov_iter.c
View filediff --git a/lib/iov_iter.c b/lib/iov_iter.c
index 6665372..2072c04 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -1921,15 +1921,29 @@ ssize_t iov_iter_extract_bvecs(struct iov_iter *iter, struct bio_vec *bv,
unsigned short max_vecs, unsigned mem_align_mask,
iov_iter_extraction_t extraction_flags)
{
- unsigned long start = (unsigned long)iter_iov_addr(iter);
unsigned short entries_left = max_vecs - *nr_vecs;
unsigned short nr_pages, i = 0;
size_t left, offset, len;
struct page **pages;
ssize_t size;
- if ((start | iter_iov_len(iter)) & mem_align_mask)
+ /*
+ * DMA engines typically have both memory address and length alignment
+ * requirements, so check these against the alignment mask. For UBUF,
+ * IOVEC and KVEC, only the current segment will be extracted from; for
+ * everything else we might extract from multiple segments, so we need
+ * to check those too.
+ */
+ if (likely(iter_is_ubuf(iter) ||
+ iter_is_iovec(iter) ||
+ iov_iter_is_kvec(iter))) {
+ unsigned long start = (unsigned long)iter_iov_addr(iter);
+
+ if ((start | iter_iov_len(iter)) & mem_align_mask)
+ return -EINVAL;
+ } else if (iov_iter_alignment(iter) & mem_align_mask) {
return -EINVAL;
+ }
/*
* Move page array up in the allocated memory for the bio vecs as far as
tools/testing/selftests/ublk/Makefile
View filediff --git a/tools/testing/selftests/ublk/Makefile b/tools/testing/selftests/ublk/Makefile
index 5daf36c..37883e9 100644
--- a/tools/testing/selftests/ublk/Makefile
+++ b/tools/testing/selftests/ublk/Makefile
@@ -73,6 +73,8 @@ TEST_PROGS += test_stress_08.sh
TEST_PROGS += test_stress_09.sh
TEST_FILES := settings
+TEST_FILES += test_common.sh
+TEST_FILES += trace
TEST_GEN_PROGS_EXTENDED = kublk metadata_size
STANDALONE_UTILS := metadata_size.c
tools/testing/selftests/ublk/test_recover_03.sh
View filediff --git a/tools/testing/selftests/ublk/test_recover_03.sh b/tools/testing/selftests/ublk/test_recover_03.sh
index 2554805..92f4012 100755
--- a/tools/testing/selftests/ublk/test_recover_03.sh
+++ b/tools/testing/selftests/ublk/test_recover_03.sh
@@ -29,6 +29,11 @@ _create_backfile 0 256M
_create_backfile 1 128M
_create_backfile 2 128M
+ublk_run_quiesce_recover -t null -q 2 -r 1 -b &
+ublk_run_quiesce_recover -t loop -q 2 -r 1 -b "${UBLK_BACKFILES[0]}" &
+ublk_run_quiesce_recover -t stripe -q 2 -r 1 -b "${UBLK_BACKFILES[1]}" "${UBLK_BACKFILES[2]}" &
+wait
+
ublk_run_quiesce_recover -t null -q 2 -r 1 &
ublk_run_quiesce_recover -t loop -q 2 -r 1 "${UBLK_BACKFILES[0]}" &
ublk_run_quiesce_recover -t stripe -q 2 -r 1 "${UBLK_BACKFILES[1]}" "${UBLK_BACKFILES[2]}" &