[PATCH 04/19] s390/dasd: Snapshot intrc before freeing the request block
Stefan Haberland <[email protected]> Wed, 5 Aug 2026 13:15:57 +0200
| Newsgroups | org.kernel.vger.linux-block,org.kernel.vger.linux-s390 |
|---|---|
| Message-ID | <[email protected]> |
__dasd_cleanup_cqr() maps the completion result to a block status by reading cqr->intrc, but only after discipline->free_cp() has returned the request block to its memory pool (dasd_eckd_free_cp() ends in dasd_sfree_request()). On SMP another CPU can reallocate that block and overwrite cqr->intrc before it is read, completing the request with the wrong error. proc_bytes is already snapshotted before free_cp() for the same reason; do the same for intrc. Reviewed-by: Jan Höppner <[email protected]> Signed-off-by: Stefan Haberland <[email protected]> --- drivers/s390/block/dasd.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 56ef38243f82..34b563917098 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -2699,17 +2699,23 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr) struct request *req; blk_status_t error = BLK_STS_OK; unsigned int proc_bytes; - int status; + int status, intrc; req = (struct request *) cqr->callback_data; dasd_profile_end(cqr->block, cqr, req); + /* + * free_cp() returns the request block to its memory pool, so snapshot + * everything still needed from cqr before calling it - another CPU can + * reallocate and overwrite the block right after. + */ proc_bytes = cqr->proc_bytes; + intrc = cqr->intrc; status = cqr->block->base->discipline->free_cp(cqr, req); if (status < 0) error = errno_to_blk_status(status); else if (status == 0) { - switch (cqr->intrc) { + switch (intrc) { case -EPERM: /* * DASD doesn't implement SCSI/NVMe reservations, but it -- 2.53.0