Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'block-6.8-2024-02-10' of git://git.kernel.dk/linux

Pull block fixes from Jens Axboe:

- NVMe pull request via Keith:
- Update a potentially stale firmware attribute (Maurizio)
- Fixes for the recent verbose error logging (Keith, Chaitanya)
- Protection information payload size fix for passthrough (Francis)

- Fix for a queue freezing issue in virtblk (Yi)

- blk-iocost underflow fix (Tejun)

- blk-wbt task detection fix (Jan)

* tag 'block-6.8-2024-02-10' of git://git.kernel.dk/linux:
virtio-blk: Ensure no requests in virtqueues before deleting vqs.
blk-iocost: Fix an UBSAN shift-out-of-bounds warning
nvme: use ns->head->pi_size instead of t10_pi_tuple structure size
nvme-core: fix comment to reflect right functions
nvme: move passthrough logging attribute to head
blk-wbt: Fix detection of dirty-throttled tasks
nvme-host: fix the updating of the firmware version

+45 -32
+7
block/blk-iocost.c
··· 1353 1353 1354 1354 lockdep_assert_held(&iocg->waitq.lock); 1355 1355 1356 + /* 1357 + * If the delay is set by another CPU, we may be in the past. No need to 1358 + * change anything if so. This avoids decay calculation underflow. 1359 + */ 1360 + if (time_before64(now->now, iocg->delay_at)) 1361 + return false; 1362 + 1356 1363 /* calculate the current delay in effect - 1/2 every second */ 1357 1364 tdelta = now->now - iocg->delay_at; 1358 1365 if (iocg->delay)
+2 -2
block/blk-wbt.c
··· 163 163 */ 164 164 static bool wb_recent_wait(struct rq_wb *rwb) 165 165 { 166 - struct bdi_writeback *wb = &rwb->rqos.disk->bdi->wb; 166 + struct backing_dev_info *bdi = rwb->rqos.disk->bdi; 167 167 168 - return time_before(jiffies, wb->dirty_sleep + HZ); 168 + return time_before(jiffies, bdi->last_bdp_sleep + HZ); 169 169 } 170 170 171 171 static inline struct rq_wait *get_rq_wait(struct rq_wb *rwb,
+4 -3
drivers/block/virtio_blk.c
··· 1593 1593 { 1594 1594 struct virtio_blk *vblk = vdev->priv; 1595 1595 1596 + /* Ensure no requests in virtqueues before deleting vqs. */ 1597 + blk_mq_freeze_queue(vblk->disk->queue); 1598 + 1596 1599 /* Ensure we don't receive any more interrupts */ 1597 1600 virtio_reset_device(vdev); 1598 1601 1599 1602 /* Make sure no work handler is accessing the device. */ 1600 1603 flush_work(&vblk->config_work); 1601 - 1602 - blk_mq_quiesce_queue(vblk->disk->queue); 1603 1604 1604 1605 vdev->config->del_vqs(vdev); 1605 1606 kfree(vblk->vqs); ··· 1619 1618 1620 1619 virtio_device_ready(vdev); 1621 1620 1622 - blk_mq_unquiesce_queue(vblk->disk->queue); 1621 + blk_mq_unfreeze_queue(vblk->disk->queue); 1623 1622 return 0; 1624 1623 } 1625 1624 #endif
+8 -6
drivers/nvme/host/core.c
··· 713 713 if (req->q->queuedata) { 714 714 struct nvme_ns *ns = req->q->disk->private_data; 715 715 716 - logging_enabled = ns->passthru_err_log_enabled; 716 + logging_enabled = ns->head->passthru_err_log_enabled; 717 717 req->timeout = NVME_IO_TIMEOUT; 718 718 } else { /* no queuedata implies admin queue */ 719 719 logging_enabled = nr->ctrl->passthru_err_log_enabled; ··· 3696 3696 3697 3697 ns->disk = disk; 3698 3698 ns->queue = disk->queue; 3699 - ns->passthru_err_log_enabled = false; 3700 3699 3701 3700 if (ctrl->opts && ctrl->opts->data_digest) 3702 3701 blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES, ns->queue); ··· 3761 3762 3762 3763 /* 3763 3764 * Set ns->disk->device->driver_data to ns so we can access 3764 - * ns->logging_enabled in nvme_passthru_err_log_enabled_store() and 3765 - * nvme_passthru_err_log_enabled_show(). 3765 + * ns->head->passthru_err_log_enabled in 3766 + * nvme_io_passthru_err_log_enabled_[store | show](). 3766 3767 */ 3767 3768 dev_set_drvdata(disk_to_dev(ns->disk), ns); 3768 3769 ··· 4190 4191 static void nvme_get_fw_slot_info(struct nvme_ctrl *ctrl) 4191 4192 { 4192 4193 struct nvme_fw_slot_info_log *log; 4194 + u8 next_fw_slot, cur_fw_slot; 4193 4195 4194 4196 log = kmalloc(sizeof(*log), GFP_KERNEL); 4195 4197 if (!log) ··· 4202 4202 goto out_free_log; 4203 4203 } 4204 4204 4205 - if (log->afi & 0x70 || !(log->afi & 0x7)) { 4205 + cur_fw_slot = log->afi & 0x7; 4206 + next_fw_slot = (log->afi & 0x70) >> 4; 4207 + if (!cur_fw_slot || (next_fw_slot && (cur_fw_slot != next_fw_slot))) { 4206 4208 dev_info(ctrl->device, 4207 4209 "Firmware is activated after next Controller Level Reset\n"); 4208 4210 goto out_free_log; 4209 4211 } 4210 4212 4211 - memcpy(ctrl->subsys->firmware_rev, &log->frs[(log->afi & 0x7) - 1], 4213 + memcpy(ctrl->subsys->firmware_rev, &log->frs[cur_fw_slot - 1], 4212 4214 sizeof(ctrl->subsys->firmware_rev)); 4213 4215 4214 4216 out_free_log:
+1 -1
drivers/nvme/host/ioctl.c
··· 228 228 length = (io.nblocks + 1) << ns->head->lba_shift; 229 229 230 230 if ((io.control & NVME_RW_PRINFO_PRACT) && 231 - ns->head->ms == sizeof(struct t10_pi_tuple)) { 231 + (ns->head->ms == ns->head->pi_size)) { 232 232 /* 233 233 * Protection information is stripped/inserted by the 234 234 * controller.
+1 -1
drivers/nvme/host/nvme.h
··· 455 455 struct list_head entry; 456 456 struct kref ref; 457 457 bool shared; 458 + bool passthru_err_log_enabled; 458 459 int instance; 459 460 struct nvme_effects_log *effects; 460 461 u64 nuse; ··· 524 523 struct device cdev_device; 525 524 526 525 struct nvme_fault_inject fault_inject; 527 - bool passthru_err_log_enabled; 528 526 }; 529 527 530 528 /* NVMe ns supports metadata actions by the controller (generate/strip) */
+15 -15
drivers/nvme/host/sysfs.c
··· 48 48 struct device_attribute *attr, const char *buf, size_t count) 49 49 { 50 50 struct nvme_ctrl *ctrl = dev_get_drvdata(dev); 51 - int err; 52 51 bool passthru_err_log_enabled; 52 + int err; 53 53 54 54 err = kstrtobool(buf, &passthru_err_log_enabled); 55 55 if (err) ··· 60 60 return count; 61 61 } 62 62 63 + static inline struct nvme_ns_head *dev_to_ns_head(struct device *dev) 64 + { 65 + struct gendisk *disk = dev_to_disk(dev); 66 + 67 + if (nvme_disk_is_ns_head(disk)) 68 + return disk->private_data; 69 + return nvme_get_ns_from_dev(dev)->head; 70 + } 71 + 63 72 static ssize_t nvme_io_passthru_err_log_enabled_show(struct device *dev, 64 73 struct device_attribute *attr, char *buf) 65 74 { 66 - struct nvme_ns *n = dev_get_drvdata(dev); 75 + struct nvme_ns_head *head = dev_to_ns_head(dev); 67 76 68 - return sysfs_emit(buf, n->passthru_err_log_enabled ? "on\n" : "off\n"); 77 + return sysfs_emit(buf, head->passthru_err_log_enabled ? "on\n" : "off\n"); 69 78 } 70 79 71 80 static ssize_t nvme_io_passthru_err_log_enabled_store(struct device *dev, 72 81 struct device_attribute *attr, const char *buf, size_t count) 73 82 { 74 - struct nvme_ns *ns = dev_get_drvdata(dev); 75 - int err; 83 + struct nvme_ns_head *head = dev_to_ns_head(dev); 76 84 bool passthru_err_log_enabled; 85 + int err; 77 86 78 87 err = kstrtobool(buf, &passthru_err_log_enabled); 79 88 if (err) 80 89 return -EINVAL; 81 - ns->passthru_err_log_enabled = passthru_err_log_enabled; 90 + head->passthru_err_log_enabled = passthru_err_log_enabled; 82 91 83 92 return count; 84 93 } ··· 99 90 static struct device_attribute dev_attr_io_passthru_err_log_enabled = \ 100 91 __ATTR(passthru_err_log_enabled, S_IRUGO | S_IWUSR, \ 101 92 nvme_io_passthru_err_log_enabled_show, nvme_io_passthru_err_log_enabled_store); 102 - 103 - static inline struct nvme_ns_head *dev_to_ns_head(struct device *dev) 104 - { 105 - struct gendisk *disk = dev_to_disk(dev); 106 - 107 - if (nvme_disk_is_ns_head(disk)) 108 - return disk->private_data; 109 - return nvme_get_ns_from_dev(dev)->head; 110 - } 111 93 112 94 static ssize_t wwid_show(struct device *dev, struct device_attribute *attr, 113 95 char *buf)
+5 -2
include/linux/backing-dev-defs.h
··· 141 141 struct delayed_work dwork; /* work item used for writeback */ 142 142 struct delayed_work bw_dwork; /* work item used for bandwidth estimate */ 143 143 144 - unsigned long dirty_sleep; /* last wait */ 145 - 146 144 struct list_head bdi_node; /* anchored at bdi->wb_list */ 147 145 148 146 #ifdef CONFIG_CGROUP_WRITEBACK ··· 177 179 * any dirty wbs, which is depended upon by bdi_has_dirty(). 178 180 */ 179 181 atomic_long_t tot_write_bandwidth; 182 + /* 183 + * Jiffies when last process was dirty throttled on this bdi. Used by 184 + * blk-wbt. 185 + */ 186 + unsigned long last_bdp_sleep; 180 187 181 188 struct bdi_writeback wb; /* the root writeback info for this bdi */ 182 189 struct list_head wb_list; /* list of all wbs */
+1 -1
mm/backing-dev.c
··· 436 436 INIT_LIST_HEAD(&wb->work_list); 437 437 INIT_DELAYED_WORK(&wb->dwork, wb_workfn); 438 438 INIT_DELAYED_WORK(&wb->bw_dwork, wb_update_bandwidth_workfn); 439 - wb->dirty_sleep = jiffies; 440 439 441 440 err = fprop_local_init_percpu(&wb->completions, gfp); 442 441 if (err) ··· 920 921 INIT_LIST_HEAD(&bdi->bdi_list); 921 922 INIT_LIST_HEAD(&bdi->wb_list); 922 923 init_waitqueue_head(&bdi->wb_waitq); 924 + bdi->last_bdp_sleep = jiffies; 923 925 924 926 return cgwb_bdi_init(bdi); 925 927 }
+1 -1
mm/page-writeback.c
··· 1921 1921 break; 1922 1922 } 1923 1923 __set_current_state(TASK_KILLABLE); 1924 - wb->dirty_sleep = now; 1924 + bdi->last_bdp_sleep = jiffies; 1925 1925 io_schedule_timeout(pause); 1926 1926 1927 1927 current->dirty_paused_when = now + pause;