Skip to content

Commit 5bc357b

Browse files
committed
Merge tag 'block-6.6-2023-09-15' of git://git.kernel.dk/linux
Pull block fixes from Jens Axboe: - NVMe pull via Keith: - nvme-tcp iov len fix (Varun) - nvme-hwmon const qualifier for safety (Krzysztof) - nvme-fc null pointer checks (Nigel) - nvme-pci no numa node fix (Pratyush) - nvme timeout fix for non-compliant controllers (Keith) - MD pull via Song fixing regressions with both 6.5 and 6.6 - Fix a use-after-free regression in resizing blk-mq tags (Chengming) * tag 'block-6.6-2023-09-15' of git://git.kernel.dk/linux: nvme: avoid bogus CRTO values md: Put the right device in md_seq_next nvme-pci: do not set the NUMA node of device if it has none blk-mq: fix tags UAF when shrinking q->nr_hw_queues md/raid1: fix error: ISO C90 forbids mixed declarations md: fix warning for holder mismatch from export_rdev() md: don't dereference mddev after export_rdev() nvme-fc: Prevent null pointer dereference in nvme_fc_io_getuuid() nvme: host: hwmon: constify pointers to hwmon_channel_info nvmet-tcp: pass iov_len instead of sg->length to bvec_set_page()
2 parents 31d8fdd + c266ae7 commit 5bc357b

File tree

9 files changed

+65
-40
lines changed

9 files changed

+65
-40
lines changed

block/blk-mq.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4405,11 +4405,8 @@ static int blk_mq_realloc_tag_set_tags(struct blk_mq_tag_set *set,
44054405
struct blk_mq_tags **new_tags;
44064406
int i;
44074407

4408-
if (set->nr_hw_queues >= new_nr_hw_queues) {
4409-
for (i = new_nr_hw_queues; i < set->nr_hw_queues; i++)
4410-
__blk_mq_free_map_and_rqs(set, i);
4408+
if (set->nr_hw_queues >= new_nr_hw_queues)
44114409
goto done;
4412-
}
44134410

44144411
new_tags = kcalloc_node(new_nr_hw_queues, sizeof(struct blk_mq_tags *),
44154412
GFP_KERNEL, set->numa_node);
@@ -4719,7 +4716,8 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
47194716
{
47204717
struct request_queue *q;
47214718
LIST_HEAD(head);
4722-
int prev_nr_hw_queues;
4719+
int prev_nr_hw_queues = set->nr_hw_queues;
4720+
int i;
47234721

47244722
lockdep_assert_held(&set->tag_list_lock);
47254723

@@ -4746,7 +4744,6 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
47464744
blk_mq_sysfs_unregister_hctxs(q);
47474745
}
47484746

4749-
prev_nr_hw_queues = set->nr_hw_queues;
47504747
if (blk_mq_realloc_tag_set_tags(set, nr_hw_queues) < 0)
47514748
goto reregister;
47524749

@@ -4781,6 +4778,10 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
47814778

47824779
list_for_each_entry(q, &set->tag_list, tag_set_list)
47834780
blk_mq_unfreeze_queue(q);
4781+
4782+
/* Free the excess tags when nr_hw_queues shrink. */
4783+
for (i = set->nr_hw_queues; i < prev_nr_hw_queues; i++)
4784+
__blk_mq_free_map_and_rqs(set, i);
47844785
}
47854786

47864787
void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues)

drivers/md/md.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -798,14 +798,14 @@ void mddev_unlock(struct mddev *mddev)
798798
} else
799799
mutex_unlock(&mddev->reconfig_mutex);
800800

801+
md_wakeup_thread(mddev->thread);
802+
wake_up(&mddev->sb_wait);
803+
801804
list_for_each_entry_safe(rdev, tmp, &delete, same_set) {
802805
list_del_init(&rdev->same_set);
803806
kobject_del(&rdev->kobj);
804807
export_rdev(rdev, mddev);
805808
}
806-
807-
md_wakeup_thread(mddev->thread);
808-
wake_up(&mddev->sb_wait);
809809
}
810810
EXPORT_SYMBOL_GPL(mddev_unlock);
811811

@@ -2452,7 +2452,8 @@ static void export_rdev(struct md_rdev *rdev, struct mddev *mddev)
24522452
if (test_bit(AutoDetected, &rdev->flags))
24532453
md_autodetect_dev(rdev->bdev->bd_dev);
24542454
#endif
2455-
blkdev_put(rdev->bdev, mddev->external ? &claim_rdev : rdev);
2455+
blkdev_put(rdev->bdev,
2456+
test_bit(Holder, &rdev->flags) ? rdev : &claim_rdev);
24562457
rdev->bdev = NULL;
24572458
kobject_put(&rdev->kobj);
24582459
}
@@ -3632,6 +3633,7 @@ EXPORT_SYMBOL_GPL(md_rdev_init);
36323633
static struct md_rdev *md_import_device(dev_t newdev, int super_format, int super_minor)
36333634
{
36343635
struct md_rdev *rdev;
3636+
struct md_rdev *holder;
36353637
sector_t size;
36363638
int err;
36373639

@@ -3646,8 +3648,15 @@ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int supe
36463648
if (err)
36473649
goto out_clear_rdev;
36483650

3651+
if (super_format == -2) {
3652+
holder = &claim_rdev;
3653+
} else {
3654+
holder = rdev;
3655+
set_bit(Holder, &rdev->flags);
3656+
}
3657+
36493658
rdev->bdev = blkdev_get_by_dev(newdev, BLK_OPEN_READ | BLK_OPEN_WRITE,
3650-
super_format == -2 ? &claim_rdev : rdev, NULL);
3659+
holder, NULL);
36513660
if (IS_ERR(rdev->bdev)) {
36523661
pr_warn("md: could not open device unknown-block(%u,%u).\n",
36533662
MAJOR(newdev), MINOR(newdev));
@@ -3684,7 +3693,7 @@ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int supe
36843693
return rdev;
36853694

36863695
out_blkdev_put:
3687-
blkdev_put(rdev->bdev, super_format == -2 ? &claim_rdev : rdev);
3696+
blkdev_put(rdev->bdev, holder);
36883697
out_clear_rdev:
36893698
md_rdev_clear(rdev);
36903699
out_free_rdev:
@@ -8256,7 +8265,7 @@ static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos)
82568265
spin_unlock(&all_mddevs_lock);
82578266

82588267
if (to_put)
8259-
mddev_put(mddev);
8268+
mddev_put(to_put);
82608269
return next_mddev;
82618270

82628271
}

drivers/md/md.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ enum flag_bits {
211211
* check if there is collision between raid1
212212
* serial bios.
213213
*/
214+
Holder, /* rdev is used as holder while opening
215+
* underlying disk exclusively.
216+
*/
214217
};
215218

216219
static inline int is_badblock(struct md_rdev *rdev, sector_t s, int sectors,

drivers/md/raid1.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,12 +1837,11 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
18371837
struct r1conf *conf = mddev->private;
18381838
int err = 0;
18391839
int number = rdev->raid_disk;
1840+
struct raid1_info *p = conf->mirrors + number;
18401841

18411842
if (unlikely(number >= conf->raid_disks))
18421843
goto abort;
18431844

1844-
struct raid1_info *p = conf->mirrors + number;
1845-
18461845
if (rdev != p->rdev)
18471846
p = conf->mirrors + conf->raid_disks + number;
18481847

drivers/nvme/host/core.c

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2245,25 +2245,8 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl)
22452245
else
22462246
ctrl->ctrl_config = NVME_CC_CSS_NVM;
22472247

2248-
if (ctrl->cap & NVME_CAP_CRMS_CRWMS) {
2249-
u32 crto;
2250-
2251-
ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CRTO, &crto);
2252-
if (ret) {
2253-
dev_err(ctrl->device, "Reading CRTO failed (%d)\n",
2254-
ret);
2255-
return ret;
2256-
}
2257-
2258-
if (ctrl->cap & NVME_CAP_CRMS_CRIMS) {
2259-
ctrl->ctrl_config |= NVME_CC_CRIME;
2260-
timeout = NVME_CRTO_CRIMT(crto);
2261-
} else {
2262-
timeout = NVME_CRTO_CRWMT(crto);
2263-
}
2264-
} else {
2265-
timeout = NVME_CAP_TIMEOUT(ctrl->cap);
2266-
}
2248+
if (ctrl->cap & NVME_CAP_CRMS_CRWMS && ctrl->cap & NVME_CAP_CRMS_CRIMS)
2249+
ctrl->ctrl_config |= NVME_CC_CRIME;
22672250

22682251
ctrl->ctrl_config |= (NVME_CTRL_PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT;
22692252
ctrl->ctrl_config |= NVME_CC_AMS_RR | NVME_CC_SHN_NONE;
@@ -2277,6 +2260,39 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl)
22772260
if (ret)
22782261
return ret;
22792262

2263+
/* CAP value may change after initial CC write */
2264+
ret = ctrl->ops->reg_read64(ctrl, NVME_REG_CAP, &ctrl->cap);
2265+
if (ret)
2266+
return ret;
2267+
2268+
timeout = NVME_CAP_TIMEOUT(ctrl->cap);
2269+
if (ctrl->cap & NVME_CAP_CRMS_CRWMS) {
2270+
u32 crto, ready_timeout;
2271+
2272+
ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CRTO, &crto);
2273+
if (ret) {
2274+
dev_err(ctrl->device, "Reading CRTO failed (%d)\n",
2275+
ret);
2276+
return ret;
2277+
}
2278+
2279+
/*
2280+
* CRTO should always be greater or equal to CAP.TO, but some
2281+
* devices are known to get this wrong. Use the larger of the
2282+
* two values.
2283+
*/
2284+
if (ctrl->ctrl_config & NVME_CC_CRIME)
2285+
ready_timeout = NVME_CRTO_CRIMT(crto);
2286+
else
2287+
ready_timeout = NVME_CRTO_CRWMT(crto);
2288+
2289+
if (ready_timeout < timeout)
2290+
dev_warn_once(ctrl->device, "bad crto:%x cap:%llx\n",
2291+
crto, ctrl->cap);
2292+
else
2293+
timeout = ready_timeout;
2294+
}
2295+
22802296
ctrl->ctrl_config |= NVME_CC_ENABLE;
22812297
ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config);
22822298
if (ret)

drivers/nvme/host/fc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1924,7 +1924,7 @@ char *nvme_fc_io_getuuid(struct nvmefc_fcp_req *req)
19241924
struct nvme_fc_fcp_op *op = fcp_req_to_fcp_op(req);
19251925
struct request *rq = op->rq;
19261926

1927-
if (!IS_ENABLED(CONFIG_BLK_CGROUP_FC_APPID) || !rq->bio)
1927+
if (!IS_ENABLED(CONFIG_BLK_CGROUP_FC_APPID) || !rq || !rq->bio)
19281928
return NULL;
19291929
return blkcg_get_fc_appid(rq->bio);
19301930
}

drivers/nvme/host/hwmon.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ static umode_t nvme_hwmon_is_visible(const void *_data,
187187
return 0;
188188
}
189189

190-
static const struct hwmon_channel_info *nvme_hwmon_info[] = {
190+
static const struct hwmon_channel_info *const nvme_hwmon_info[] = {
191191
HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
192192
HWMON_CHANNEL_INFO(temp,
193193
HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MIN |

drivers/nvme/host/pci.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2916,9 +2916,6 @@ static struct nvme_dev *nvme_pci_alloc_dev(struct pci_dev *pdev,
29162916
struct nvme_dev *dev;
29172917
int ret = -ENOMEM;
29182918

2919-
if (node == NUMA_NO_NODE)
2920-
set_dev_node(&pdev->dev, first_memory_node);
2921-
29222919
dev = kzalloc_node(sizeof(*dev), GFP_KERNEL, node);
29232920
if (!dev)
29242921
return ERR_PTR(-ENOMEM);

drivers/nvme/target/tcp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ static void nvmet_tcp_build_pdu_iovec(struct nvmet_tcp_cmd *cmd)
348348
while (length) {
349349
u32 iov_len = min_t(u32, length, sg->length - sg_offset);
350350

351-
bvec_set_page(iov, sg_page(sg), sg->length,
351+
bvec_set_page(iov, sg_page(sg), iov_len,
352352
sg->offset + sg_offset);
353353

354354
length -= iov_len;

0 commit comments

Comments
 (0)