From: Greg Kroah-Hartman Date: Mon, 16 Jan 2023 14:49:53 +0000 (+0100) Subject: 6.1-stable patches X-Git-Tag: v4.14.303~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=087c9832110b06e91336f0ed91ae9e9e52100095;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: block-handle-bio_split_to_limits-null-return.patch drm-i915-fix-cfi-violations-in-gt_sysfs.patch io_uring-io-wq-free-worker-if-task_work-creation-is-canceled.patch io_uring-io-wq-only-free-worker-if-it-was-allocated-for-creation.patch --- diff --git a/queue-6.1/block-handle-bio_split_to_limits-null-return.patch b/queue-6.1/block-handle-bio_split_to_limits-null-return.patch new file mode 100644 index 00000000000..32b3183f37e --- /dev/null +++ b/queue-6.1/block-handle-bio_split_to_limits-null-return.patch @@ -0,0 +1,124 @@ +From 613b14884b8595e20b9fac4126bf627313827fbe Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Wed, 4 Jan 2023 08:51:19 -0700 +Subject: block: handle bio_split_to_limits() NULL return + +From: Jens Axboe + +commit 613b14884b8595e20b9fac4126bf627313827fbe upstream. + +This can't happen right now, but in preparation for allowing +bio_split_to_limits() returning NULL if it ended the bio, check for it +in all the callers. + +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + block/blk-merge.c | 4 +++- + block/blk-mq.c | 5 ++++- + drivers/block/drbd/drbd_req.c | 2 ++ + drivers/block/ps3vram.c | 2 ++ + drivers/md/dm.c | 2 ++ + drivers/md/md.c | 2 ++ + drivers/nvme/host/multipath.c | 2 ++ + drivers/s390/block/dcssblk.c | 2 ++ + 8 files changed, 19 insertions(+), 2 deletions(-) + +--- a/block/blk-merge.c ++++ b/block/blk-merge.c +@@ -358,11 +358,13 @@ struct bio *__bio_split_to_limits(struct + default: + split = bio_split_rw(bio, lim, nr_segs, bs, + get_max_io_size(bio, lim) << SECTOR_SHIFT); ++ if (IS_ERR(split)) ++ return NULL; + break; + } + + if (split) { +- /* there isn't chance to merge the splitted bio */ ++ /* there isn't chance to merge the split bio */ + split->bi_opf |= REQ_NOMERGE; + + blkcg_bio_issue_init(split); +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -2919,8 +2919,11 @@ void blk_mq_submit_bio(struct bio *bio) + blk_status_t ret; + + bio = blk_queue_bounce(bio, q); +- if (bio_may_exceed_limits(bio, &q->limits)) ++ if (bio_may_exceed_limits(bio, &q->limits)) { + bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); ++ if (!bio) ++ return; ++ } + + if (!bio_integrity_prep(bio)) + return; +--- a/drivers/block/drbd/drbd_req.c ++++ b/drivers/block/drbd/drbd_req.c +@@ -1607,6 +1607,8 @@ void drbd_submit_bio(struct bio *bio) + struct drbd_device *device = bio->bi_bdev->bd_disk->private_data; + + bio = bio_split_to_limits(bio); ++ if (!bio) ++ return; + + /* + * what we "blindly" assume: +--- a/drivers/block/ps3vram.c ++++ b/drivers/block/ps3vram.c +@@ -587,6 +587,8 @@ static void ps3vram_submit_bio(struct bi + dev_dbg(&dev->core, "%s\n", __func__); + + bio = bio_split_to_limits(bio); ++ if (!bio) ++ return; + + spin_lock_irq(&priv->lock); + busy = !bio_list_empty(&priv->list); +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -1755,6 +1755,8 @@ static void dm_split_and_process_bio(str + * otherwise associated queue_limits won't be imposed. + */ + bio = bio_split_to_limits(bio); ++ if (!bio) ++ return; + } + + init_clone_info(&ci, md, map, bio, is_abnormal); +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -443,6 +443,8 @@ static void md_submit_bio(struct bio *bi + } + + bio = bio_split_to_limits(bio); ++ if (!bio) ++ return; + + if (mddev->ro == 1 && unlikely(rw == WRITE)) { + if (bio_sectors(bio) != 0) +--- a/drivers/nvme/host/multipath.c ++++ b/drivers/nvme/host/multipath.c +@@ -351,6 +351,8 @@ static void nvme_ns_head_submit_bio(stru + * pool from the original queue to allocate the bvecs from. + */ + bio = bio_split_to_limits(bio); ++ if (!bio) ++ return; + + srcu_idx = srcu_read_lock(&head->srcu); + ns = nvme_find_path(head); +--- a/drivers/s390/block/dcssblk.c ++++ b/drivers/s390/block/dcssblk.c +@@ -865,6 +865,8 @@ dcssblk_submit_bio(struct bio *bio) + unsigned long bytes_done; + + bio = bio_split_to_limits(bio); ++ if (!bio) ++ return; + + bytes_done = 0; + dev_info = bio->bi_bdev->bd_disk->private_data; diff --git a/queue-6.1/drm-i915-fix-cfi-violations-in-gt_sysfs.patch b/queue-6.1/drm-i915-fix-cfi-violations-in-gt_sysfs.patch new file mode 100644 index 00000000000..20ca64fc6e5 --- /dev/null +++ b/queue-6.1/drm-i915-fix-cfi-violations-in-gt_sysfs.patch @@ -0,0 +1,912 @@ +From a8a4f0467d706fc22d286dfa973946e5944b793c Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Tue, 25 Oct 2022 21:50:15 +0200 +Subject: drm/i915: Fix CFI violations in gt_sysfs + +From: Nathan Chancellor + +commit a8a4f0467d706fc22d286dfa973946e5944b793c upstream. + +When booting with CONFIG_CFI_CLANG, there are numerous violations when +accessing the files under +/sys/devices/pci0000:00/0000:00:02.0/drm/card0/gt/gt0: + + $ cd /sys/devices/pci0000:00/0000:00:02.0/drm/card0/gt/gt0 + + $ grep . * + id:0 + punit_req_freq_mhz:350 + rc6_enable:1 + rc6_residency_ms:214934 + rps_act_freq_mhz:1300 + rps_boost_freq_mhz:1300 + rps_cur_freq_mhz:350 + rps_max_freq_mhz:1300 + rps_min_freq_mhz:350 + rps_RP0_freq_mhz:1300 + rps_RP1_freq_mhz:350 + rps_RPn_freq_mhz:350 + throttle_reason_pl1:0 + throttle_reason_pl2:0 + throttle_reason_pl4:0 + throttle_reason_prochot:0 + throttle_reason_ratl:0 + throttle_reason_status:0 + throttle_reason_thermal:0 + throttle_reason_vr_tdc:0 + throttle_reason_vr_thermalert:0 + + $ sudo dmesg &| grep "CFI failure at" + [ 214.595903] CFI failure at kobj_attr_show+0x19/0x30 (target: id_show+0x0/0x70 [i915]; expected type: 0xc527b809) + [ 214.596064] CFI failure at kobj_attr_show+0x19/0x30 (target: punit_req_freq_mhz_show+0x0/0x40 [i915]; expected type: 0xc527b809) + [ 214.596407] CFI failure at kobj_attr_show+0x19/0x30 (target: rc6_enable_show+0x0/0x40 [i915]; expected type: 0xc527b809) + [ 214.596528] CFI failure at kobj_attr_show+0x19/0x30 (target: rc6_residency_ms_show+0x0/0x270 [i915]; expected type: 0xc527b809) + [ 214.596682] CFI failure at kobj_attr_show+0x19/0x30 (target: act_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809) + [ 214.596792] CFI failure at kobj_attr_show+0x19/0x30 (target: boost_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809) + [ 214.596893] CFI failure at kobj_attr_show+0x19/0x30 (target: cur_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809) + [ 214.596996] CFI failure at kobj_attr_show+0x19/0x30 (target: max_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809) + [ 214.597099] CFI failure at kobj_attr_show+0x19/0x30 (target: min_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809) + [ 214.597198] CFI failure at kobj_attr_show+0x19/0x30 (target: RP0_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809) + [ 214.597301] CFI failure at kobj_attr_show+0x19/0x30 (target: RP1_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809) + [ 214.597405] CFI failure at kobj_attr_show+0x19/0x30 (target: RPn_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809) + [ 214.597538] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809) + [ 214.597701] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809) + [ 214.597836] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809) + [ 214.597952] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809) + [ 214.598071] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809) + [ 214.598177] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809) + [ 214.598307] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809) + [ 214.598439] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809) + [ 214.598542] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809) + +With kCFI, indirect calls are validated against their expected type +versus actual type and failures occur when the two types do not match. +The ultimate issue is that these sysfs functions are expecting to be +called via dev_attr_show() but they may also be called via +kobj_attr_show(), as certain files are created under two different +kobjects that have two different sysfs_ops in intel_gt_sysfs_register(), +hence the warnings above. When accessing the gt_ files under +/sys/devices/pci0000:00/0000:00:02.0/drm/card0, which are using the same +sysfs functions, there are no violations, meaning the functions are +being called with the proper type. + +To make everything work properly, adjust certain functions to match the +type of the ->show() and ->store() members in 'struct kobj_attribute'. +Add a macro to generate functions for that can be called via both +dev_attr_{show,store}() or kobj_attr_{show,store}() so that they can be +called through both kobject locations without violating kCFI and adjust +the attribute groups to account for this. + +Link: https://github.com/ClangBuiltLinux/linux/issues/1716 +Reviewed-by: Andi Shyti +Reviewed-by: Andrzej Hajda +Reviewed-by: Kees Cook +Signed-off-by: Nathan Chancellor +Signed-off-by: Andi Shyti +Link: https://patchwork.freedesktop.org/patch/msgid/20221013205909.1282545-1-nathan@kernel.org +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/gt/intel_gt_sysfs.c | 15 + drivers/gpu/drm/i915/gt/intel_gt_sysfs.h | 2 + drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c | 459 ++++++++++++---------------- + 3 files changed, 219 insertions(+), 257 deletions(-) + +--- a/drivers/gpu/drm/i915/gt/intel_gt_sysfs.c ++++ b/drivers/gpu/drm/i915/gt/intel_gt_sysfs.c +@@ -22,11 +22,9 @@ bool is_object_gt(struct kobject *kobj) + return !strncmp(kobj->name, "gt", 2); + } + +-struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev, ++struct intel_gt *intel_gt_sysfs_get_drvdata(struct kobject *kobj, + const char *name) + { +- struct kobject *kobj = &dev->kobj; +- + /* + * We are interested at knowing from where the interface + * has been called, whether it's called from gt/ or from +@@ -38,6 +36,7 @@ struct intel_gt *intel_gt_sysfs_get_drvd + * "struct drm_i915_private *" type. + */ + if (!is_object_gt(kobj)) { ++ struct device *dev = kobj_to_dev(kobj); + struct drm_i915_private *i915 = kdev_minor_to_i915(dev); + + return to_gt(i915); +@@ -51,18 +50,18 @@ static struct kobject *gt_get_parent_obj + return >->i915->drm.primary->kdev->kobj; + } + +-static ssize_t id_show(struct device *dev, +- struct device_attribute *attr, ++static ssize_t id_show(struct kobject *kobj, ++ struct kobj_attribute *attr, + char *buf) + { +- struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name); ++ struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); + + return sysfs_emit(buf, "%u\n", gt->info.id); + } +-static DEVICE_ATTR_RO(id); ++static struct kobj_attribute attr_id = __ATTR_RO(id); + + static struct attribute *id_attrs[] = { +- &dev_attr_id.attr, ++ &attr_id.attr, + NULL, + }; + ATTRIBUTE_GROUPS(id); +--- a/drivers/gpu/drm/i915/gt/intel_gt_sysfs.h ++++ b/drivers/gpu/drm/i915/gt/intel_gt_sysfs.h +@@ -30,7 +30,7 @@ static inline struct intel_gt *kobj_to_g + + void intel_gt_sysfs_register(struct intel_gt *gt); + void intel_gt_sysfs_unregister(struct intel_gt *gt); +-struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev, ++struct intel_gt *intel_gt_sysfs_get_drvdata(struct kobject *kobj, + const char *name); + + #endif /* SYSFS_GT_H */ +--- a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c ++++ b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c +@@ -24,14 +24,15 @@ enum intel_gt_sysfs_op { + }; + + static int +-sysfs_gt_attribute_w_func(struct device *dev, struct device_attribute *attr, ++sysfs_gt_attribute_w_func(struct kobject *kobj, struct attribute *attr, + int (func)(struct intel_gt *gt, u32 val), u32 val) + { + struct intel_gt *gt; + int ret; + +- if (!is_object_gt(&dev->kobj)) { ++ if (!is_object_gt(kobj)) { + int i; ++ struct device *dev = kobj_to_dev(kobj); + struct drm_i915_private *i915 = kdev_minor_to_i915(dev); + + for_each_gt(gt, i915, i) { +@@ -40,7 +41,7 @@ sysfs_gt_attribute_w_func(struct device + break; + } + } else { +- gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name); ++ gt = intel_gt_sysfs_get_drvdata(kobj, attr->name); + ret = func(gt, val); + } + +@@ -48,7 +49,7 @@ sysfs_gt_attribute_w_func(struct device + } + + static u32 +-sysfs_gt_attribute_r_func(struct device *dev, struct device_attribute *attr, ++sysfs_gt_attribute_r_func(struct kobject *kobj, struct attribute *attr, + u32 (func)(struct intel_gt *gt), + enum intel_gt_sysfs_op op) + { +@@ -57,8 +58,9 @@ sysfs_gt_attribute_r_func(struct device + + ret = (op == INTEL_GT_SYSFS_MAX) ? 0 : (u32) -1; + +- if (!is_object_gt(&dev->kobj)) { ++ if (!is_object_gt(kobj)) { + int i; ++ struct device *dev = kobj_to_dev(kobj); + struct drm_i915_private *i915 = kdev_minor_to_i915(dev); + + for_each_gt(gt, i915, i) { +@@ -77,7 +79,7 @@ sysfs_gt_attribute_r_func(struct device + } + } + } else { +- gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name); ++ gt = intel_gt_sysfs_get_drvdata(kobj, attr->name); + ret = func(gt); + } + +@@ -92,6 +94,76 @@ sysfs_gt_attribute_r_func(struct device + #define sysfs_gt_attribute_r_max_func(d, a, f) \ + sysfs_gt_attribute_r_func(d, a, f, INTEL_GT_SYSFS_MAX) + ++#define INTEL_GT_SYSFS_SHOW(_name, _attr_type) \ ++ static ssize_t _name##_show_common(struct kobject *kobj, \ ++ struct attribute *attr, char *buff) \ ++ { \ ++ u32 val = sysfs_gt_attribute_r_##_attr_type##_func(kobj, attr, \ ++ __##_name##_show); \ ++ \ ++ return sysfs_emit(buff, "%u\n", val); \ ++ } \ ++ static ssize_t _name##_show(struct kobject *kobj, \ ++ struct kobj_attribute *attr, char *buff) \ ++ { \ ++ return _name ##_show_common(kobj, &attr->attr, buff); \ ++ } \ ++ static ssize_t _name##_dev_show(struct device *dev, \ ++ struct device_attribute *attr, char *buff) \ ++ { \ ++ return _name##_show_common(&dev->kobj, &attr->attr, buff); \ ++ } ++ ++#define INTEL_GT_SYSFS_STORE(_name, _func) \ ++ static ssize_t _name##_store_common(struct kobject *kobj, \ ++ struct attribute *attr, \ ++ const char *buff, size_t count) \ ++ { \ ++ int ret; \ ++ u32 val; \ ++ \ ++ ret = kstrtou32(buff, 0, &val); \ ++ if (ret) \ ++ return ret; \ ++ \ ++ ret = sysfs_gt_attribute_w_func(kobj, attr, _func, val); \ ++ \ ++ return ret ?: count; \ ++ } \ ++ static ssize_t _name##_store(struct kobject *kobj, \ ++ struct kobj_attribute *attr, const char *buff, \ ++ size_t count) \ ++ { \ ++ return _name##_store_common(kobj, &attr->attr, buff, count); \ ++ } \ ++ static ssize_t _name##_dev_store(struct device *dev, \ ++ struct device_attribute *attr, \ ++ const char *buff, size_t count) \ ++ { \ ++ return _name##_store_common(&dev->kobj, &attr->attr, buff, count); \ ++ } ++ ++#define INTEL_GT_SYSFS_SHOW_MAX(_name) INTEL_GT_SYSFS_SHOW(_name, max) ++#define INTEL_GT_SYSFS_SHOW_MIN(_name) INTEL_GT_SYSFS_SHOW(_name, min) ++ ++#define INTEL_GT_ATTR_RW(_name) \ ++ static struct kobj_attribute attr_##_name = __ATTR_RW(_name) ++ ++#define INTEL_GT_ATTR_RO(_name) \ ++ static struct kobj_attribute attr_##_name = __ATTR_RO(_name) ++ ++#define INTEL_GT_DUAL_ATTR_RW(_name) \ ++ static struct device_attribute dev_attr_##_name = __ATTR(_name, 0644, \ ++ _name##_dev_show, \ ++ _name##_dev_store); \ ++ INTEL_GT_ATTR_RW(_name) ++ ++#define INTEL_GT_DUAL_ATTR_RO(_name) \ ++ static struct device_attribute dev_attr_##_name = __ATTR(_name, 0444, \ ++ _name##_dev_show, \ ++ NULL); \ ++ INTEL_GT_ATTR_RO(_name) ++ + #ifdef CONFIG_PM + static u32 get_residency(struct intel_gt *gt, i915_reg_t reg) + { +@@ -104,11 +176,8 @@ static u32 get_residency(struct intel_gt + return DIV_ROUND_CLOSEST_ULL(res, 1000); + } + +-static ssize_t rc6_enable_show(struct device *dev, +- struct device_attribute *attr, +- char *buff) ++static u8 get_rc6_mask(struct intel_gt *gt) + { +- struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name); + u8 mask = 0; + + if (HAS_RC6(gt->i915)) +@@ -118,37 +187,35 @@ static ssize_t rc6_enable_show(struct de + if (HAS_RC6pp(gt->i915)) + mask |= BIT(2); + +- return sysfs_emit(buff, "%x\n", mask); ++ return mask; + } + +-static u32 __rc6_residency_ms_show(struct intel_gt *gt) ++static ssize_t rc6_enable_show(struct kobject *kobj, ++ struct kobj_attribute *attr, ++ char *buff) + { +- return get_residency(gt, GEN6_GT_GFX_RC6); ++ struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); ++ ++ return sysfs_emit(buff, "%x\n", get_rc6_mask(gt)); + } + +-static ssize_t rc6_residency_ms_show(struct device *dev, +- struct device_attribute *attr, +- char *buff) ++static ssize_t rc6_enable_dev_show(struct device *dev, ++ struct device_attribute *attr, ++ char *buff) + { +- u32 rc6_residency = sysfs_gt_attribute_r_min_func(dev, attr, +- __rc6_residency_ms_show); ++ struct intel_gt *gt = intel_gt_sysfs_get_drvdata(&dev->kobj, attr->attr.name); + +- return sysfs_emit(buff, "%u\n", rc6_residency); ++ return sysfs_emit(buff, "%x\n", get_rc6_mask(gt)); + } + +-static u32 __rc6p_residency_ms_show(struct intel_gt *gt) ++static u32 __rc6_residency_ms_show(struct intel_gt *gt) + { +- return get_residency(gt, GEN6_GT_GFX_RC6p); ++ return get_residency(gt, GEN6_GT_GFX_RC6); + } + +-static ssize_t rc6p_residency_ms_show(struct device *dev, +- struct device_attribute *attr, +- char *buff) ++static u32 __rc6p_residency_ms_show(struct intel_gt *gt) + { +- u32 rc6p_residency = sysfs_gt_attribute_r_min_func(dev, attr, +- __rc6p_residency_ms_show); +- +- return sysfs_emit(buff, "%u\n", rc6p_residency); ++ return get_residency(gt, GEN6_GT_GFX_RC6p); + } + + static u32 __rc6pp_residency_ms_show(struct intel_gt *gt) +@@ -156,67 +223,69 @@ static u32 __rc6pp_residency_ms_show(str + return get_residency(gt, GEN6_GT_GFX_RC6pp); + } + +-static ssize_t rc6pp_residency_ms_show(struct device *dev, +- struct device_attribute *attr, +- char *buff) +-{ +- u32 rc6pp_residency = sysfs_gt_attribute_r_min_func(dev, attr, +- __rc6pp_residency_ms_show); +- +- return sysfs_emit(buff, "%u\n", rc6pp_residency); +-} +- + static u32 __media_rc6_residency_ms_show(struct intel_gt *gt) + { + return get_residency(gt, VLV_GT_MEDIA_RC6); + } + +-static ssize_t media_rc6_residency_ms_show(struct device *dev, +- struct device_attribute *attr, +- char *buff) +-{ +- u32 rc6_residency = sysfs_gt_attribute_r_min_func(dev, attr, +- __media_rc6_residency_ms_show); ++INTEL_GT_SYSFS_SHOW_MIN(rc6_residency_ms); ++INTEL_GT_SYSFS_SHOW_MIN(rc6p_residency_ms); ++INTEL_GT_SYSFS_SHOW_MIN(rc6pp_residency_ms); ++INTEL_GT_SYSFS_SHOW_MIN(media_rc6_residency_ms); ++ ++INTEL_GT_DUAL_ATTR_RO(rc6_enable); ++INTEL_GT_DUAL_ATTR_RO(rc6_residency_ms); ++INTEL_GT_DUAL_ATTR_RO(rc6p_residency_ms); ++INTEL_GT_DUAL_ATTR_RO(rc6pp_residency_ms); ++INTEL_GT_DUAL_ATTR_RO(media_rc6_residency_ms); + +- return sysfs_emit(buff, "%u\n", rc6_residency); +-} ++static struct attribute *rc6_attrs[] = { ++ &attr_rc6_enable.attr, ++ &attr_rc6_residency_ms.attr, ++ NULL ++}; + +-static DEVICE_ATTR_RO(rc6_enable); +-static DEVICE_ATTR_RO(rc6_residency_ms); +-static DEVICE_ATTR_RO(rc6p_residency_ms); +-static DEVICE_ATTR_RO(rc6pp_residency_ms); +-static DEVICE_ATTR_RO(media_rc6_residency_ms); ++static struct attribute *rc6p_attrs[] = { ++ &attr_rc6p_residency_ms.attr, ++ &attr_rc6pp_residency_ms.attr, ++ NULL ++}; + +-static struct attribute *rc6_attrs[] = { ++static struct attribute *media_rc6_attrs[] = { ++ &attr_media_rc6_residency_ms.attr, ++ NULL ++}; ++ ++static struct attribute *rc6_dev_attrs[] = { + &dev_attr_rc6_enable.attr, + &dev_attr_rc6_residency_ms.attr, + NULL + }; + +-static struct attribute *rc6p_attrs[] = { ++static struct attribute *rc6p_dev_attrs[] = { + &dev_attr_rc6p_residency_ms.attr, + &dev_attr_rc6pp_residency_ms.attr, + NULL + }; + +-static struct attribute *media_rc6_attrs[] = { ++static struct attribute *media_rc6_dev_attrs[] = { + &dev_attr_media_rc6_residency_ms.attr, + NULL + }; + + static const struct attribute_group rc6_attr_group[] = { + { .attrs = rc6_attrs, }, +- { .name = power_group_name, .attrs = rc6_attrs, }, ++ { .name = power_group_name, .attrs = rc6_dev_attrs, }, + }; + + static const struct attribute_group rc6p_attr_group[] = { + { .attrs = rc6p_attrs, }, +- { .name = power_group_name, .attrs = rc6p_attrs, }, ++ { .name = power_group_name, .attrs = rc6p_dev_attrs, }, + }; + + static const struct attribute_group media_rc6_attr_group[] = { + { .attrs = media_rc6_attrs, }, +- { .name = power_group_name, .attrs = media_rc6_attrs, }, ++ { .name = power_group_name, .attrs = media_rc6_dev_attrs, }, + }; + + static int __intel_gt_sysfs_create_group(struct kobject *kobj, +@@ -271,104 +340,34 @@ static u32 __act_freq_mhz_show(struct in + return intel_rps_read_actual_frequency(>->rps); + } + +-static ssize_t act_freq_mhz_show(struct device *dev, +- struct device_attribute *attr, char *buff) +-{ +- u32 actual_freq = sysfs_gt_attribute_r_max_func(dev, attr, +- __act_freq_mhz_show); +- +- return sysfs_emit(buff, "%u\n", actual_freq); +-} +- + static u32 __cur_freq_mhz_show(struct intel_gt *gt) + { + return intel_rps_get_requested_frequency(>->rps); + } + +-static ssize_t cur_freq_mhz_show(struct device *dev, +- struct device_attribute *attr, char *buff) +-{ +- u32 cur_freq = sysfs_gt_attribute_r_max_func(dev, attr, +- __cur_freq_mhz_show); +- +- return sysfs_emit(buff, "%u\n", cur_freq); +-} +- + static u32 __boost_freq_mhz_show(struct intel_gt *gt) + { + return intel_rps_get_boost_frequency(>->rps); + } + +-static ssize_t boost_freq_mhz_show(struct device *dev, +- struct device_attribute *attr, +- char *buff) +-{ +- u32 boost_freq = sysfs_gt_attribute_r_max_func(dev, attr, +- __boost_freq_mhz_show); +- +- return sysfs_emit(buff, "%u\n", boost_freq); +-} +- + static int __boost_freq_mhz_store(struct intel_gt *gt, u32 val) + { + return intel_rps_set_boost_frequency(>->rps, val); + } + +-static ssize_t boost_freq_mhz_store(struct device *dev, +- struct device_attribute *attr, +- const char *buff, size_t count) +-{ +- ssize_t ret; +- u32 val; +- +- ret = kstrtou32(buff, 0, &val); +- if (ret) +- return ret; +- +- return sysfs_gt_attribute_w_func(dev, attr, +- __boost_freq_mhz_store, val) ?: count; +-} +- +-static u32 __rp0_freq_mhz_show(struct intel_gt *gt) ++static u32 __RP0_freq_mhz_show(struct intel_gt *gt) + { + return intel_rps_get_rp0_frequency(>->rps); + } + +-static ssize_t RP0_freq_mhz_show(struct device *dev, +- struct device_attribute *attr, char *buff) +-{ +- u32 rp0_freq = sysfs_gt_attribute_r_max_func(dev, attr, +- __rp0_freq_mhz_show); +- +- return sysfs_emit(buff, "%u\n", rp0_freq); +-} +- +-static u32 __rp1_freq_mhz_show(struct intel_gt *gt) +-{ +- return intel_rps_get_rp1_frequency(>->rps); +-} +- +-static ssize_t RP1_freq_mhz_show(struct device *dev, +- struct device_attribute *attr, char *buff) +-{ +- u32 rp1_freq = sysfs_gt_attribute_r_max_func(dev, attr, +- __rp1_freq_mhz_show); +- +- return sysfs_emit(buff, "%u\n", rp1_freq); +-} +- +-static u32 __rpn_freq_mhz_show(struct intel_gt *gt) ++static u32 __RPn_freq_mhz_show(struct intel_gt *gt) + { + return intel_rps_get_rpn_frequency(>->rps); + } + +-static ssize_t RPn_freq_mhz_show(struct device *dev, +- struct device_attribute *attr, char *buff) ++static u32 __RP1_freq_mhz_show(struct intel_gt *gt) + { +- u32 rpn_freq = sysfs_gt_attribute_r_max_func(dev, attr, +- __rpn_freq_mhz_show); +- +- return sysfs_emit(buff, "%u\n", rpn_freq); ++ return intel_rps_get_rp1_frequency(>->rps); + } + + static u32 __max_freq_mhz_show(struct intel_gt *gt) +@@ -376,71 +375,21 @@ static u32 __max_freq_mhz_show(struct in + return intel_rps_get_max_frequency(>->rps); + } + +-static ssize_t max_freq_mhz_show(struct device *dev, +- struct device_attribute *attr, char *buff) +-{ +- u32 max_freq = sysfs_gt_attribute_r_max_func(dev, attr, +- __max_freq_mhz_show); +- +- return sysfs_emit(buff, "%u\n", max_freq); +-} +- + static int __set_max_freq(struct intel_gt *gt, u32 val) + { + return intel_rps_set_max_frequency(>->rps, val); + } + +-static ssize_t max_freq_mhz_store(struct device *dev, +- struct device_attribute *attr, +- const char *buff, size_t count) +-{ +- int ret; +- u32 val; +- +- ret = kstrtou32(buff, 0, &val); +- if (ret) +- return ret; +- +- ret = sysfs_gt_attribute_w_func(dev, attr, __set_max_freq, val); +- +- return ret ?: count; +-} +- + static u32 __min_freq_mhz_show(struct intel_gt *gt) + { + return intel_rps_get_min_frequency(>->rps); + } + +-static ssize_t min_freq_mhz_show(struct device *dev, +- struct device_attribute *attr, char *buff) +-{ +- u32 min_freq = sysfs_gt_attribute_r_min_func(dev, attr, +- __min_freq_mhz_show); +- +- return sysfs_emit(buff, "%u\n", min_freq); +-} +- + static int __set_min_freq(struct intel_gt *gt, u32 val) + { + return intel_rps_set_min_frequency(>->rps, val); + } + +-static ssize_t min_freq_mhz_store(struct device *dev, +- struct device_attribute *attr, +- const char *buff, size_t count) +-{ +- int ret; +- u32 val; +- +- ret = kstrtou32(buff, 0, &val); +- if (ret) +- return ret; +- +- ret = sysfs_gt_attribute_w_func(dev, attr, __set_min_freq, val); +- +- return ret ?: count; +-} +- + static u32 __vlv_rpe_freq_mhz_show(struct intel_gt *gt) + { + struct intel_rps *rps = >->rps; +@@ -448,23 +397,31 @@ static u32 __vlv_rpe_freq_mhz_show(struc + return intel_gpu_freq(rps, rps->efficient_freq); + } + +-static ssize_t vlv_rpe_freq_mhz_show(struct device *dev, +- struct device_attribute *attr, char *buff) +-{ +- u32 rpe_freq = sysfs_gt_attribute_r_max_func(dev, attr, +- __vlv_rpe_freq_mhz_show); +- +- return sysfs_emit(buff, "%u\n", rpe_freq); +-} +- +-#define INTEL_GT_RPS_SYSFS_ATTR(_name, _mode, _show, _store) \ +- static struct device_attribute dev_attr_gt_##_name = __ATTR(gt_##_name, _mode, _show, _store); \ +- static struct device_attribute dev_attr_rps_##_name = __ATTR(rps_##_name, _mode, _show, _store) +- +-#define INTEL_GT_RPS_SYSFS_ATTR_RO(_name) \ +- INTEL_GT_RPS_SYSFS_ATTR(_name, 0444, _name##_show, NULL) +-#define INTEL_GT_RPS_SYSFS_ATTR_RW(_name) \ +- INTEL_GT_RPS_SYSFS_ATTR(_name, 0644, _name##_show, _name##_store) ++INTEL_GT_SYSFS_SHOW_MAX(act_freq_mhz); ++INTEL_GT_SYSFS_SHOW_MAX(boost_freq_mhz); ++INTEL_GT_SYSFS_SHOW_MAX(cur_freq_mhz); ++INTEL_GT_SYSFS_SHOW_MAX(RP0_freq_mhz); ++INTEL_GT_SYSFS_SHOW_MAX(RP1_freq_mhz); ++INTEL_GT_SYSFS_SHOW_MAX(RPn_freq_mhz); ++INTEL_GT_SYSFS_SHOW_MAX(max_freq_mhz); ++INTEL_GT_SYSFS_SHOW_MIN(min_freq_mhz); ++INTEL_GT_SYSFS_SHOW_MAX(vlv_rpe_freq_mhz); ++INTEL_GT_SYSFS_STORE(boost_freq_mhz, __boost_freq_mhz_store); ++INTEL_GT_SYSFS_STORE(max_freq_mhz, __set_max_freq); ++INTEL_GT_SYSFS_STORE(min_freq_mhz, __set_min_freq); ++ ++#define INTEL_GT_RPS_SYSFS_ATTR(_name, _mode, _show, _store, _show_dev, _store_dev) \ ++ static struct device_attribute dev_attr_gt_##_name = __ATTR(gt_##_name, _mode, \ ++ _show_dev, _store_dev); \ ++ static struct kobj_attribute attr_rps_##_name = __ATTR(rps_##_name, _mode, \ ++ _show, _store) ++ ++#define INTEL_GT_RPS_SYSFS_ATTR_RO(_name) \ ++ INTEL_GT_RPS_SYSFS_ATTR(_name, 0444, _name##_show, NULL, \ ++ _name##_dev_show, NULL) ++#define INTEL_GT_RPS_SYSFS_ATTR_RW(_name) \ ++ INTEL_GT_RPS_SYSFS_ATTR(_name, 0644, _name##_show, _name##_store, \ ++ _name##_dev_show, _name##_dev_store) + + /* The below macros generate static structures */ + INTEL_GT_RPS_SYSFS_ATTR_RO(act_freq_mhz); +@@ -475,32 +432,31 @@ INTEL_GT_RPS_SYSFS_ATTR_RO(RP1_freq_mhz) + INTEL_GT_RPS_SYSFS_ATTR_RO(RPn_freq_mhz); + INTEL_GT_RPS_SYSFS_ATTR_RW(max_freq_mhz); + INTEL_GT_RPS_SYSFS_ATTR_RW(min_freq_mhz); ++INTEL_GT_RPS_SYSFS_ATTR_RO(vlv_rpe_freq_mhz); + +-static DEVICE_ATTR_RO(vlv_rpe_freq_mhz); +- +-#define GEN6_ATTR(s) { \ +- &dev_attr_##s##_act_freq_mhz.attr, \ +- &dev_attr_##s##_cur_freq_mhz.attr, \ +- &dev_attr_##s##_boost_freq_mhz.attr, \ +- &dev_attr_##s##_max_freq_mhz.attr, \ +- &dev_attr_##s##_min_freq_mhz.attr, \ +- &dev_attr_##s##_RP0_freq_mhz.attr, \ +- &dev_attr_##s##_RP1_freq_mhz.attr, \ +- &dev_attr_##s##_RPn_freq_mhz.attr, \ ++#define GEN6_ATTR(p, s) { \ ++ &p##attr_##s##_act_freq_mhz.attr, \ ++ &p##attr_##s##_cur_freq_mhz.attr, \ ++ &p##attr_##s##_boost_freq_mhz.attr, \ ++ &p##attr_##s##_max_freq_mhz.attr, \ ++ &p##attr_##s##_min_freq_mhz.attr, \ ++ &p##attr_##s##_RP0_freq_mhz.attr, \ ++ &p##attr_##s##_RP1_freq_mhz.attr, \ ++ &p##attr_##s##_RPn_freq_mhz.attr, \ + NULL, \ + } + +-#define GEN6_RPS_ATTR GEN6_ATTR(rps) +-#define GEN6_GT_ATTR GEN6_ATTR(gt) ++#define GEN6_RPS_ATTR GEN6_ATTR(, rps) ++#define GEN6_GT_ATTR GEN6_ATTR(dev_, gt) + + static const struct attribute * const gen6_rps_attrs[] = GEN6_RPS_ATTR; + static const struct attribute * const gen6_gt_attrs[] = GEN6_GT_ATTR; + +-static ssize_t punit_req_freq_mhz_show(struct device *dev, +- struct device_attribute *attr, ++static ssize_t punit_req_freq_mhz_show(struct kobject *kobj, ++ struct kobj_attribute *attr, + char *buff) + { +- struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name); ++ struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); + u32 preq = intel_rps_read_punit_req_frequency(>->rps); + + return sysfs_emit(buff, "%u\n", preq); +@@ -508,17 +464,17 @@ static ssize_t punit_req_freq_mhz_show(s + + struct intel_gt_bool_throttle_attr { + struct attribute attr; +- ssize_t (*show)(struct device *dev, struct device_attribute *attr, ++ ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, + char *buf); + i915_reg_t reg32; + u32 mask; + }; + +-static ssize_t throttle_reason_bool_show(struct device *dev, +- struct device_attribute *attr, ++static ssize_t throttle_reason_bool_show(struct kobject *kobj, ++ struct kobj_attribute *attr, + char *buff) + { +- struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name); ++ struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); + struct intel_gt_bool_throttle_attr *t_attr = + (struct intel_gt_bool_throttle_attr *) attr; + bool val = rps_read_mask_mmio(>->rps, t_attr->reg32, t_attr->mask); +@@ -534,7 +490,7 @@ struct intel_gt_bool_throttle_attr attr_ + .mask = mask__, \ + } + +-static DEVICE_ATTR_RO(punit_req_freq_mhz); ++INTEL_GT_ATTR_RO(punit_req_freq_mhz); + static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_status, GT0_PERF_LIMIT_REASONS_MASK); + static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_pl1, POWER_LIMIT_1_MASK); + static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_pl2, POWER_LIMIT_2_MASK); +@@ -597,8 +553,8 @@ static const struct attribute *throttle_ + #define U8_8_VAL_MASK 0xffff + #define U8_8_SCALE_TO_VALUE "0.00390625" + +-static ssize_t freq_factor_scale_show(struct device *dev, +- struct device_attribute *attr, ++static ssize_t freq_factor_scale_show(struct kobject *kobj, ++ struct kobj_attribute *attr, + char *buff) + { + return sysfs_emit(buff, "%s\n", U8_8_SCALE_TO_VALUE); +@@ -610,11 +566,11 @@ static u32 media_ratio_mode_to_factor(u3 + return !mode ? mode : 256 / mode; + } + +-static ssize_t media_freq_factor_show(struct device *dev, +- struct device_attribute *attr, ++static ssize_t media_freq_factor_show(struct kobject *kobj, ++ struct kobj_attribute *attr, + char *buff) + { +- struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name); ++ struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); + struct intel_guc_slpc *slpc = >->uc.guc.slpc; + intel_wakeref_t wakeref; + u32 mode; +@@ -641,11 +597,11 @@ static ssize_t media_freq_factor_show(st + return sysfs_emit(buff, "%u\n", media_ratio_mode_to_factor(mode)); + } + +-static ssize_t media_freq_factor_store(struct device *dev, +- struct device_attribute *attr, ++static ssize_t media_freq_factor_store(struct kobject *kobj, ++ struct kobj_attribute *attr, + const char *buff, size_t count) + { +- struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name); ++ struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); + struct intel_guc_slpc *slpc = >->uc.guc.slpc; + u32 factor, mode; + int err; +@@ -670,11 +626,11 @@ static ssize_t media_freq_factor_store(s + return err ?: count; + } + +-static ssize_t media_RP0_freq_mhz_show(struct device *dev, +- struct device_attribute *attr, ++static ssize_t media_RP0_freq_mhz_show(struct kobject *kobj, ++ struct kobj_attribute *attr, + char *buff) + { +- struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name); ++ struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); + u32 val; + int err; + +@@ -691,11 +647,11 @@ static ssize_t media_RP0_freq_mhz_show(s + return sysfs_emit(buff, "%u\n", val); + } + +-static ssize_t media_RPn_freq_mhz_show(struct device *dev, +- struct device_attribute *attr, ++static ssize_t media_RPn_freq_mhz_show(struct kobject *kobj, ++ struct kobj_attribute *attr, + char *buff) + { +- struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name); ++ struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); + u32 val; + int err; + +@@ -712,17 +668,17 @@ static ssize_t media_RPn_freq_mhz_show(s + return sysfs_emit(buff, "%u\n", val); + } + +-static DEVICE_ATTR_RW(media_freq_factor); +-static struct device_attribute dev_attr_media_freq_factor_scale = ++INTEL_GT_ATTR_RW(media_freq_factor); ++static struct kobj_attribute attr_media_freq_factor_scale = + __ATTR(media_freq_factor.scale, 0444, freq_factor_scale_show, NULL); +-static DEVICE_ATTR_RO(media_RP0_freq_mhz); +-static DEVICE_ATTR_RO(media_RPn_freq_mhz); ++INTEL_GT_ATTR_RO(media_RP0_freq_mhz); ++INTEL_GT_ATTR_RO(media_RPn_freq_mhz); + + static const struct attribute *media_perf_power_attrs[] = { +- &dev_attr_media_freq_factor.attr, +- &dev_attr_media_freq_factor_scale.attr, +- &dev_attr_media_RP0_freq_mhz.attr, +- &dev_attr_media_RPn_freq_mhz.attr, ++ &attr_media_freq_factor.attr, ++ &attr_media_freq_factor_scale.attr, ++ &attr_media_RP0_freq_mhz.attr, ++ &attr_media_RPn_freq_mhz.attr, + NULL + }; + +@@ -754,20 +710,29 @@ static const struct attribute * const rp + NULL + }; + +-static int intel_sysfs_rps_init(struct intel_gt *gt, struct kobject *kobj, +- const struct attribute * const *attrs) ++static int intel_sysfs_rps_init(struct intel_gt *gt, struct kobject *kobj) + { ++ const struct attribute * const *attrs; ++ struct attribute *vlv_attr; + int ret; + + if (GRAPHICS_VER(gt->i915) < 6) + return 0; + ++ if (is_object_gt(kobj)) { ++ attrs = gen6_rps_attrs; ++ vlv_attr = &attr_rps_vlv_rpe_freq_mhz.attr; ++ } else { ++ attrs = gen6_gt_attrs; ++ vlv_attr = &dev_attr_gt_vlv_rpe_freq_mhz.attr; ++ } ++ + ret = sysfs_create_files(kobj, attrs); + if (ret) + return ret; + + if (IS_VALLEYVIEW(gt->i915) || IS_CHERRYVIEW(gt->i915)) +- ret = sysfs_create_file(kobj, &dev_attr_vlv_rpe_freq_mhz.attr); ++ ret = sysfs_create_file(kobj, vlv_attr); + + return ret; + } +@@ -778,9 +743,7 @@ void intel_gt_sysfs_pm_init(struct intel + + intel_sysfs_rc6_init(gt, kobj); + +- ret = is_object_gt(kobj) ? +- intel_sysfs_rps_init(gt, kobj, gen6_rps_attrs) : +- intel_sysfs_rps_init(gt, kobj, gen6_gt_attrs); ++ ret = intel_sysfs_rps_init(gt, kobj); + if (ret) + drm_warn(>->i915->drm, + "failed to create gt%u RPS sysfs files (%pe)", +@@ -790,7 +753,7 @@ void intel_gt_sysfs_pm_init(struct intel + if (!is_object_gt(kobj)) + return; + +- ret = sysfs_create_file(kobj, &dev_attr_punit_req_freq_mhz.attr); ++ ret = sysfs_create_file(kobj, &attr_punit_req_freq_mhz.attr); + if (ret) + drm_warn(>->i915->drm, + "failed to create gt%u punit_req_freq_mhz sysfs (%pe)", diff --git a/queue-6.1/io_uring-io-wq-free-worker-if-task_work-creation-is-canceled.patch b/queue-6.1/io_uring-io-wq-free-worker-if-task_work-creation-is-canceled.patch new file mode 100644 index 00000000000..f753aff7f4a --- /dev/null +++ b/queue-6.1/io_uring-io-wq-free-worker-if-task_work-creation-is-canceled.patch @@ -0,0 +1,34 @@ +From af82425c6a2d2f347c79b63ce74fca6dc6be157f Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Mon, 2 Jan 2023 16:49:46 -0700 +Subject: io_uring/io-wq: free worker if task_work creation is canceled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jens Axboe + +commit af82425c6a2d2f347c79b63ce74fca6dc6be157f upstream. + +If we cancel the task_work, the worker will never come into existance. +As this is the last reference to it, ensure that we get it freed +appropriately. + +Cc: stable@vger.kernel.org +Reported-by: 진호 +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + io_uring/io-wq.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/io_uring/io-wq.c ++++ b/io_uring/io-wq.c +@@ -1230,6 +1230,7 @@ static void io_wq_cancel_tw_create(struc + + worker = container_of(cb, struct io_worker, create_work); + io_worker_cancel_cb(worker); ++ kfree(worker); + } + } + diff --git a/queue-6.1/io_uring-io-wq-only-free-worker-if-it-was-allocated-for-creation.patch b/queue-6.1/io_uring-io-wq-only-free-worker-if-it-was-allocated-for-creation.patch new file mode 100644 index 00000000000..0caf72f0498 --- /dev/null +++ b/queue-6.1/io_uring-io-wq-only-free-worker-if-it-was-allocated-for-creation.patch @@ -0,0 +1,38 @@ +From e6db6f9398dadcbc06318a133d4c44a2d3844e61 Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Sun, 8 Jan 2023 10:39:17 -0700 +Subject: io_uring/io-wq: only free worker if it was allocated for creation + +From: Jens Axboe + +commit e6db6f9398dadcbc06318a133d4c44a2d3844e61 upstream. + +We have two types of task_work based creation, one is using an existing +worker to setup a new one (eg when going to sleep and we have no free +workers), and the other is allocating a new worker. Only the latter +should be freed when we cancel task_work creation for a new worker. + +Fixes: af82425c6a2d ("io_uring/io-wq: free worker if task_work creation is canceled") +Reported-by: syzbot+d56ec896af3637bdb7e4@syzkaller.appspotmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + io_uring/io-wq.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/io_uring/io-wq.c ++++ b/io_uring/io-wq.c +@@ -1230,7 +1230,12 @@ static void io_wq_cancel_tw_create(struc + + worker = container_of(cb, struct io_worker, create_work); + io_worker_cancel_cb(worker); +- kfree(worker); ++ /* ++ * Only the worker continuation helper has worker allocated and ++ * hence needs freeing. ++ */ ++ if (cb->func == create_worker_cont) ++ kfree(worker); + } + } + diff --git a/queue-6.1/io_uring-poll-attempt-request-issue-after-racy-poll-.patch b/queue-6.1/io_uring-poll-attempt-request-issue-after-racy-poll-.patch index e7356e2354a..a9fef1e85ba 100644 --- a/queue-6.1/io_uring-poll-attempt-request-issue-after-racy-poll-.patch +++ b/queue-6.1/io_uring-poll-attempt-request-issue-after-racy-poll-.patch @@ -28,11 +28,9 @@ Fixes: eb0089d629ba ("io_uring: single shot poll removal optimisation") Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- - io_uring/poll.c | 33 ++++++++++++++++++++++----------- + io_uring/poll.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) -diff --git a/io_uring/poll.c b/io_uring/poll.c -index df42fd8a6ab0..f2f9f174fc62 100644 --- a/io_uring/poll.c +++ b/io_uring/poll.c @@ -223,22 +223,23 @@ enum { @@ -65,7 +63,7 @@ index df42fd8a6ab0..f2f9f174fc62 100644 /* req->task == current here, checking PF_EXITING is safe */ if (unlikely(req->task->flags & PF_EXITING)) -@@ -274,10 +275,15 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked) +@@ -274,10 +275,15 @@ static int io_poll_check_events(struct i if (!req->cqe.res) { struct poll_table_struct pt = { ._key = req->apoll_events }; req->cqe.res = vfs_poll(req->file, &pt) & req->apoll_events; @@ -84,7 +82,7 @@ index df42fd8a6ab0..f2f9f174fc62 100644 if (req->apoll_events & EPOLLONESHOT) return IOU_POLL_DONE; if (io_is_uring_fops(req->file)) -@@ -294,7 +300,7 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked) +@@ -294,7 +300,7 @@ static int io_poll_check_events(struct i return IOU_POLL_REMOVE_POLL_USE_RES; } } else { @@ -93,7 +91,7 @@ index df42fd8a6ab0..f2f9f174fc62 100644 if (ret == IOU_STOP_MULTISHOT) return IOU_POLL_REMOVE_POLL_USE_RES; if (ret < 0) -@@ -325,6 +331,11 @@ static void io_poll_task_func(struct io_kiocb *req, bool *locked) +@@ -325,6 +331,11 @@ static void io_poll_task_func(struct io_ if (ret == IOU_POLL_DONE) { struct io_poll *poll = io_kiocb_to_cmd(req, struct io_poll); req->cqe.res = mangle_poll(req->cqe.res & poll->events); @@ -105,7 +103,7 @@ index df42fd8a6ab0..f2f9f174fc62 100644 } else if (ret != IOU_POLL_REMOVE_POLL_USE_RES) { req->cqe.res = ret; req_set_fail(req); -@@ -350,7 +361,7 @@ static void io_apoll_task_func(struct io_kiocb *req, bool *locked) +@@ -350,7 +361,7 @@ static void io_apoll_task_func(struct io if (ret == IOU_POLL_REMOVE_POLL_USE_RES) io_req_complete_post(req); @@ -114,6 +112,3 @@ index df42fd8a6ab0..f2f9f174fc62 100644 io_req_task_submit(req, locked); else io_req_complete_failed(req, ret); --- -2.35.1 - diff --git a/queue-6.1/series b/queue-6.1/series index 25f18e5969f..a934165a5b3 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -175,3 +175,7 @@ alsa-usb-audio-fix-possible-null-pointer-dereference.patch efi-fix-null-deref-in-init-error-path.patch io_uring-lock-overflowing-for-iopoll.patch io_uring-poll-attempt-request-issue-after-racy-poll-.patch +drm-i915-fix-cfi-violations-in-gt_sysfs.patch +io_uring-io-wq-free-worker-if-task_work-creation-is-canceled.patch +io_uring-io-wq-only-free-worker-if-it-was-allocated-for-creation.patch +block-handle-bio_split_to_limits-null-return.patch