Skip to content

Commit 990f320

Browse files
committed
Merge tag 'block-6.1-2022-11-25' of git://git.kernel.dk/linux
Pull block fixes from Jens Axboe: - A few fixes for s390 sads (Stefan, Colin) - Ensure that ublk doesn't reorder requests, as that can be problematic on devices that need specific ordering (Ming) - Fix a queue reference leak in disk allocation handling (Christoph) * tag 'block-6.1-2022-11-25' of git://git.kernel.dk/linux: ublk_drv: don't forward io commands in reserve order s390/dasd: fix possible buffer overflow in copy_pair_show s390/dasd: fix no record found for raw_track_access s390/dasd: increase printing of debug data payload s390/dasd: Fix spelling mistake "Ivalid" -> "Invalid" blk-mq: fix queue reference leak on blk_mq_alloc_disk_for_queue failure
2 parents 364eb61 + 7d4a931 commit 990f320

File tree

5 files changed

+67
-69
lines changed

5 files changed

+67
-69
lines changed

block/blk-mq.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4045,9 +4045,14 @@ EXPORT_SYMBOL(__blk_mq_alloc_disk);
40454045
struct gendisk *blk_mq_alloc_disk_for_queue(struct request_queue *q,
40464046
struct lock_class_key *lkclass)
40474047
{
4048+
struct gendisk *disk;
4049+
40484050
if (!blk_get_queue(q))
40494051
return NULL;
4050-
return __alloc_disk_node(q, NUMA_NO_NODE, lkclass);
4052+
disk = __alloc_disk_node(q, NUMA_NO_NODE, lkclass);
4053+
if (!disk)
4054+
blk_put_queue(q);
4055+
return disk;
40514056
}
40524057
EXPORT_SYMBOL(blk_mq_alloc_disk_for_queue);
40534058

drivers/block/ublk_drv.c

Lines changed: 38 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,8 @@
5757
#define UBLK_PARAM_TYPE_ALL (UBLK_PARAM_TYPE_BASIC | UBLK_PARAM_TYPE_DISCARD)
5858

5959
struct ublk_rq_data {
60-
union {
61-
struct callback_head work;
62-
struct llist_node node;
63-
};
60+
struct llist_node node;
61+
struct callback_head work;
6462
};
6563

6664
struct ublk_uring_cmd_pdu {
@@ -766,30 +764,52 @@ static inline void __ublk_rq_task_work(struct request *req)
766764
ubq_complete_io_cmd(io, UBLK_IO_RES_OK);
767765
}
768766

767+
static inline void ublk_forward_io_cmds(struct ublk_queue *ubq)
768+
{
769+
struct llist_node *io_cmds = llist_del_all(&ubq->io_cmds);
770+
struct ublk_rq_data *data, *tmp;
771+
772+
io_cmds = llist_reverse_order(io_cmds);
773+
llist_for_each_entry_safe(data, tmp, io_cmds, node)
774+
__ublk_rq_task_work(blk_mq_rq_from_pdu(data));
775+
}
776+
777+
static inline void ublk_abort_io_cmds(struct ublk_queue *ubq)
778+
{
779+
struct llist_node *io_cmds = llist_del_all(&ubq->io_cmds);
780+
struct ublk_rq_data *data, *tmp;
781+
782+
llist_for_each_entry_safe(data, tmp, io_cmds, node)
783+
__ublk_abort_rq(ubq, blk_mq_rq_from_pdu(data));
784+
}
785+
769786
static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd)
770787
{
771788
struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
772789
struct ublk_queue *ubq = pdu->ubq;
773-
struct llist_node *io_cmds = llist_del_all(&ubq->io_cmds);
774-
struct ublk_rq_data *data;
775790

776-
llist_for_each_entry(data, io_cmds, node)
777-
__ublk_rq_task_work(blk_mq_rq_from_pdu(data));
791+
ublk_forward_io_cmds(ubq);
778792
}
779793

780794
static void ublk_rq_task_work_fn(struct callback_head *work)
781795
{
782796
struct ublk_rq_data *data = container_of(work,
783797
struct ublk_rq_data, work);
784798
struct request *req = blk_mq_rq_from_pdu(data);
799+
struct ublk_queue *ubq = req->mq_hctx->driver_data;
785800

786-
__ublk_rq_task_work(req);
801+
ublk_forward_io_cmds(ubq);
787802
}
788803

789-
static void ublk_submit_cmd(struct ublk_queue *ubq, const struct request *rq)
804+
static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq)
790805
{
791-
struct ublk_io *io = &ubq->ios[rq->tag];
806+
struct ublk_rq_data *data = blk_mq_rq_to_pdu(rq);
807+
struct ublk_io *io;
792808

809+
if (!llist_add(&data->node, &ubq->io_cmds))
810+
return;
811+
812+
io = &ubq->ios[rq->tag];
793813
/*
794814
* If the check pass, we know that this is a re-issued request aborted
795815
* previously in monitor_work because the ubq_daemon(cmd's task) is
@@ -803,11 +823,11 @@ static void ublk_submit_cmd(struct ublk_queue *ubq, const struct request *rq)
803823
* guarantees that here is a re-issued request aborted previously.
804824
*/
805825
if (unlikely(io->flags & UBLK_IO_FLAG_ABORTED)) {
806-
struct llist_node *io_cmds = llist_del_all(&ubq->io_cmds);
807-
struct ublk_rq_data *data;
808-
809-
llist_for_each_entry(data, io_cmds, node)
810-
__ublk_abort_rq(ubq, blk_mq_rq_from_pdu(data));
826+
ublk_abort_io_cmds(ubq);
827+
} else if (ublk_can_use_task_work(ubq)) {
828+
if (task_work_add(ubq->ubq_daemon, &data->work,
829+
TWA_SIGNAL_NO_IPI))
830+
ublk_abort_io_cmds(ubq);
811831
} else {
812832
struct io_uring_cmd *cmd = io->cmd;
813833
struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
@@ -817,23 +837,6 @@ static void ublk_submit_cmd(struct ublk_queue *ubq, const struct request *rq)
817837
}
818838
}
819839

820-
static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq,
821-
bool last)
822-
{
823-
struct ublk_rq_data *data = blk_mq_rq_to_pdu(rq);
824-
825-
if (ublk_can_use_task_work(ubq)) {
826-
enum task_work_notify_mode notify_mode = last ?
827-
TWA_SIGNAL_NO_IPI : TWA_NONE;
828-
829-
if (task_work_add(ubq->ubq_daemon, &data->work, notify_mode))
830-
__ublk_abort_rq(ubq, rq);
831-
} else {
832-
if (llist_add(&data->node, &ubq->io_cmds))
833-
ublk_submit_cmd(ubq, rq);
834-
}
835-
}
836-
837840
static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx,
838841
const struct blk_mq_queue_data *bd)
839842
{
@@ -865,19 +868,11 @@ static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx,
865868
return BLK_STS_OK;
866869
}
867870

868-
ublk_queue_cmd(ubq, rq, bd->last);
871+
ublk_queue_cmd(ubq, rq);
869872

870873
return BLK_STS_OK;
871874
}
872875

873-
static void ublk_commit_rqs(struct blk_mq_hw_ctx *hctx)
874-
{
875-
struct ublk_queue *ubq = hctx->driver_data;
876-
877-
if (ublk_can_use_task_work(ubq))
878-
__set_notify_signal(ubq->ubq_daemon);
879-
}
880-
881876
static int ublk_init_hctx(struct blk_mq_hw_ctx *hctx, void *driver_data,
882877
unsigned int hctx_idx)
883878
{
@@ -899,7 +894,6 @@ static int ublk_init_rq(struct blk_mq_tag_set *set, struct request *req,
899894

900895
static const struct blk_mq_ops ublk_mq_ops = {
901896
.queue_rq = ublk_queue_rq,
902-
.commit_rqs = ublk_commit_rqs,
903897
.init_hctx = ublk_init_hctx,
904898
.init_request = ublk_init_rq,
905899
};
@@ -1197,7 +1191,7 @@ static void ublk_handle_need_get_data(struct ublk_device *ub, int q_id,
11971191
struct ublk_queue *ubq = ublk_get_queue(ub, q_id);
11981192
struct request *req = blk_mq_tag_to_rq(ub->tag_set.tags[q_id], tag);
11991193

1200-
ublk_queue_cmd(ubq, req, true);
1194+
ublk_queue_cmd(ubq, req);
12011195
}
12021196

12031197
static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)

drivers/s390/block/dasd_devmap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1954,7 +1954,7 @@ dasd_copy_pair_show(struct device *dev,
19541954
break;
19551955
}
19561956
}
1957-
if (!copy->entry[i].primary)
1957+
if (i == DASD_CP_ENTRIES)
19581958
goto out;
19591959

19601960
/* print all secondary */

drivers/s390/block/dasd_eckd.c

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4722,7 +4722,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
47224722
struct dasd_device *basedev;
47234723
struct req_iterator iter;
47244724
struct dasd_ccw_req *cqr;
4725-
unsigned int first_offs;
47264725
unsigned int trkcount;
47274726
unsigned long *idaws;
47284727
unsigned int size;
@@ -4756,7 +4755,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
47564755
last_trk = (blk_rq_pos(req) + blk_rq_sectors(req) - 1) /
47574756
DASD_RAW_SECTORS_PER_TRACK;
47584757
trkcount = last_trk - first_trk + 1;
4759-
first_offs = 0;
47604758

47614759
if (rq_data_dir(req) == READ)
47624760
cmd = DASD_ECKD_CCW_READ_TRACK;
@@ -4800,13 +4798,13 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
48004798

48014799
if (use_prefix) {
48024800
prefix_LRE(ccw++, data, first_trk, last_trk, cmd, basedev,
4803-
startdev, 1, first_offs + 1, trkcount, 0, 0);
4801+
startdev, 1, 0, trkcount, 0, 0);
48044802
} else {
48054803
define_extent(ccw++, data, first_trk, last_trk, cmd, basedev, 0);
48064804
ccw[-1].flags |= CCW_FLAG_CC;
48074805

48084806
data += sizeof(struct DE_eckd_data);
4809-
locate_record_ext(ccw++, data, first_trk, first_offs + 1,
4807+
locate_record_ext(ccw++, data, first_trk, 0,
48104808
trkcount, cmd, basedev, 0, 0);
48114809
}
48124810

@@ -5500,7 +5498,7 @@ dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp)
55005498
* Dump the range of CCWs into 'page' buffer
55015499
* and return number of printed chars.
55025500
*/
5503-
static int
5501+
static void
55045502
dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)
55055503
{
55065504
int len, count;
@@ -5518,16 +5516,21 @@ dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)
55185516
else
55195517
datap = (char *) ((addr_t) from->cda);
55205518

5521-
/* dump data (max 32 bytes) */
5522-
for (count = 0; count < from->count && count < 32; count++) {
5523-
if (count % 8 == 0) len += sprintf(page + len, " ");
5524-
if (count % 4 == 0) len += sprintf(page + len, " ");
5519+
/* dump data (max 128 bytes) */
5520+
for (count = 0; count < from->count && count < 128; count++) {
5521+
if (count % 32 == 0)
5522+
len += sprintf(page + len, "\n");
5523+
if (count % 8 == 0)
5524+
len += sprintf(page + len, " ");
5525+
if (count % 4 == 0)
5526+
len += sprintf(page + len, " ");
55255527
len += sprintf(page + len, "%02x", datap[count]);
55265528
}
55275529
len += sprintf(page + len, "\n");
55285530
from++;
55295531
}
5530-
return len;
5532+
if (len > 0)
5533+
printk(KERN_ERR "%s", page);
55315534
}
55325535

55335536
static void
@@ -5619,37 +5622,33 @@ static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
56195622
if (req) {
56205623
/* req == NULL for unsolicited interrupts */
56215624
/* dump the Channel Program (max 140 Bytes per line) */
5622-
/* Count CCW and print first CCWs (maximum 1024 % 140 = 7) */
5625+
/* Count CCW and print first CCWs (maximum 7) */
56235626
first = req->cpaddr;
56245627
for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++);
56255628
to = min(first + 6, last);
5626-
len = sprintf(page, PRINTK_HEADER
5627-
" Related CP in req: %p\n", req);
5628-
dasd_eckd_dump_ccw_range(first, to, page + len);
5629-
printk(KERN_ERR "%s", page);
5629+
printk(KERN_ERR PRINTK_HEADER " Related CP in req: %p\n", req);
5630+
dasd_eckd_dump_ccw_range(first, to, page);
56305631

56315632
/* print failing CCW area (maximum 4) */
56325633
/* scsw->cda is either valid or zero */
5633-
len = 0;
56345634
from = ++to;
56355635
fail = (struct ccw1 *)(addr_t)
56365636
irb->scsw.cmd.cpa; /* failing CCW */
56375637
if (from < fail - 2) {
56385638
from = fail - 2; /* there is a gap - print header */
5639-
len += sprintf(page, PRINTK_HEADER "......\n");
5639+
printk(KERN_ERR PRINTK_HEADER "......\n");
56405640
}
56415641
to = min(fail + 1, last);
5642-
len += dasd_eckd_dump_ccw_range(from, to, page + len);
5642+
dasd_eckd_dump_ccw_range(from, to, page + len);
56435643

56445644
/* print last CCWs (maximum 2) */
5645+
len = 0;
56455646
from = max(from, ++to);
56465647
if (from < last - 1) {
56475648
from = last - 1; /* there is a gap - print header */
5648-
len += sprintf(page + len, PRINTK_HEADER "......\n");
5649+
printk(KERN_ERR PRINTK_HEADER "......\n");
56495650
}
5650-
len += dasd_eckd_dump_ccw_range(from, last, page + len);
5651-
if (len > 0)
5652-
printk(KERN_ERR "%s", page);
5651+
dasd_eckd_dump_ccw_range(from, last, page + len);
56535652
}
56545653
free_page((unsigned long) page);
56555654
}

drivers/s390/block/dasd_ioctl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ dasd_ioctl_copy_pair_swap(struct block_device *bdev, void __user *argp)
401401
return -EFAULT;
402402
}
403403
if (memchr_inv(data.reserved, 0, sizeof(data.reserved))) {
404-
pr_warn("%s: Ivalid swap data specified.\n",
404+
pr_warn("%s: Invalid swap data specified\n",
405405
dev_name(&device->cdev->dev));
406406
dasd_put_device(device);
407407
return DASD_COPYPAIRSWAP_INVALID;

0 commit comments

Comments
 (0)