From: Greg Kroah-Hartman Date: Fri, 10 Mar 2023 13:05:17 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v6.1.17~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=14d925aac84a534e163ec2bf7f949bdea3a277c8;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: f2fs-fix-cgroup-writeback-accounting-with-fs-layer-encryption.patch media-uvcvideo-fix-race-condition-with-usb_kill_urb.patch media-uvcvideo-provide-sync-and-async-uvc_ctrl_status_event.patch thermal-intel-powerclamp-fix-cur_state-for-multi-package-system.patch --- diff --git a/queue-4.19/f2fs-fix-cgroup-writeback-accounting-with-fs-layer-encryption.patch b/queue-4.19/f2fs-fix-cgroup-writeback-accounting-with-fs-layer-encryption.patch new file mode 100644 index 00000000000..292f3ce487e --- /dev/null +++ b/queue-4.19/f2fs-fix-cgroup-writeback-accounting-with-fs-layer-encryption.patch @@ -0,0 +1,54 @@ +From 844545c51a5b2a524b22a2fe9d0b353b827d24b4 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Thu, 2 Feb 2023 17:02:39 -0800 +Subject: f2fs: fix cgroup writeback accounting with fs-layer encryption + +From: Eric Biggers + +commit 844545c51a5b2a524b22a2fe9d0b353b827d24b4 upstream. + +When writing a page from an encrypted file that is using +filesystem-layer encryption (not inline encryption), f2fs encrypts the +pagecache page into a bounce page, then writes the bounce page. + +It also passes the bounce page to wbc_account_cgroup_owner(). That's +incorrect, because the bounce page is a newly allocated temporary page +that doesn't have the memory cgroup of the original pagecache page. +This makes wbc_account_cgroup_owner() not account the I/O to the owner +of the pagecache page as it should. + +Fix this by always passing the pagecache page to +wbc_account_cgroup_owner(). + +Fixes: 578c647879f7 ("f2fs: implement cgroup writeback support") +Cc: stable@vger.kernel.org +Reported-by: Matthew Wilcox (Oracle) +Signed-off-by: Eric Biggers +Acked-by: Tejun Heo +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/data.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -464,7 +464,7 @@ int f2fs_submit_page_bio(struct f2fs_io_ + } + + if (fio->io_wbc && !is_read_io(fio->op)) +- wbc_account_io(fio->io_wbc, page, PAGE_SIZE); ++ wbc_account_io(fio->io_wbc, fio->page, PAGE_SIZE); + + bio_set_op_attrs(bio, fio->op, fio->op_flags); + +@@ -533,7 +533,7 @@ alloc_new: + } + + if (fio->io_wbc) +- wbc_account_io(fio->io_wbc, bio_page, PAGE_SIZE); ++ wbc_account_io(fio->io_wbc, fio->page, PAGE_SIZE); + + io->last_block_in_bio = fio->new_blkaddr; + f2fs_trace_ios(fio, 0); diff --git a/queue-4.19/media-uvcvideo-fix-race-condition-with-usb_kill_urb.patch b/queue-4.19/media-uvcvideo-fix-race-condition-with-usb_kill_urb.patch new file mode 100644 index 00000000000..c1490a80f3a --- /dev/null +++ b/queue-4.19/media-uvcvideo-fix-race-condition-with-usb_kill_urb.patch @@ -0,0 +1,140 @@ +From 619d9b710cf06f7a00a17120ca92333684ac45a8 Mon Sep 17 00:00:00 2001 +From: Ricardo Ribalda +Date: Thu, 5 Jan 2023 15:31:29 +0100 +Subject: media: uvcvideo: Fix race condition with usb_kill_urb + +From: Ricardo Ribalda + +commit 619d9b710cf06f7a00a17120ca92333684ac45a8 upstream. + +usb_kill_urb warranties that all the handlers are finished when it +returns, but does not protect against threads that might be handling +asynchronously the urb. + +For UVC, the function uvc_ctrl_status_event_async() takes care of +control changes asynchronously. + +If the code is executed in the following order: + +CPU 0 CPU 1 +===== ===== +uvc_status_complete() + uvc_status_stop() +uvc_ctrl_status_event_work() + uvc_status_start() -> FAIL + +Then uvc_status_start will keep failing and this error will be shown: + +<4>[ 5.540139] URB 0000000000000000 submitted while active +drivers/usb/core/urb.c:378 usb_submit_urb+0x4c3/0x528 + +Let's improve the current situation, by not re-submiting the urb if +we are stopping the status event. Also process the queued work +(if any) during stop. + +CPU 0 CPU 1 +===== ===== +uvc_status_complete() + uvc_status_stop() + uvc_status_start() +uvc_ctrl_status_event_work() -> FAIL + +Hopefully, with the usb layer protection this should be enough to cover +all the cases. + +Cc: stable@vger.kernel.org +Fixes: e5225c820c05 ("media: uvcvideo: Send a control event when a Control Change interrupt arrives") +Reviewed-by: Yunke Cao +Signed-off-by: Ricardo Ribalda +Reviewed-by: Laurent Pinchart +Signed-off-by: Laurent Pinchart +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/uvc/uvc_ctrl.c | 5 +++++ + drivers/media/usb/uvc/uvc_status.c | 37 +++++++++++++++++++++++++++++++++++++ + drivers/media/usb/uvc/uvcvideo.h | 1 + + 3 files changed, 43 insertions(+) + +--- a/drivers/media/usb/uvc/uvc_ctrl.c ++++ b/drivers/media/usb/uvc/uvc_ctrl.c +@@ -11,6 +11,7 @@ + * + */ + ++#include + #include + #include + #include +@@ -1323,6 +1324,10 @@ static void uvc_ctrl_status_event_work(s + + uvc_ctrl_status_event(w->chain, w->ctrl, w->data); + ++ /* The barrier is needed to synchronize with uvc_status_stop(). */ ++ if (smp_load_acquire(&dev->flush_status)) ++ return; ++ + /* Resubmit the URB. */ + w->urb->interval = dev->int_ep->desc.bInterval; + ret = usb_submit_urb(w->urb, GFP_KERNEL); +--- a/drivers/media/usb/uvc/uvc_status.c ++++ b/drivers/media/usb/uvc/uvc_status.c +@@ -11,6 +11,7 @@ + * + */ + ++#include + #include + #include + #include +@@ -315,5 +316,41 @@ int uvc_status_start(struct uvc_device * + + void uvc_status_stop(struct uvc_device *dev) + { ++ struct uvc_ctrl_work *w = &dev->async_ctrl; ++ ++ /* ++ * Prevent the asynchronous control handler from requeing the URB. The ++ * barrier is needed so the flush_status change is visible to other ++ * CPUs running the asynchronous handler before usb_kill_urb() is ++ * called below. ++ */ ++ smp_store_release(&dev->flush_status, true); ++ ++ /* ++ * Cancel any pending asynchronous work. If any status event was queued, ++ * process it synchronously. ++ */ ++ if (cancel_work_sync(&w->work)) ++ uvc_ctrl_status_event(w->chain, w->ctrl, w->data); ++ ++ /* Kill the urb. */ + usb_kill_urb(dev->int_urb); ++ ++ /* ++ * The URB completion handler may have queued asynchronous work. This ++ * won't resubmit the URB as flush_status is set, but it needs to be ++ * cancelled before returning or it could then race with a future ++ * uvc_status_start() call. ++ */ ++ if (cancel_work_sync(&w->work)) ++ uvc_ctrl_status_event(w->chain, w->ctrl, w->data); ++ ++ /* ++ * From this point, there are no events on the queue and the status URB ++ * is dead. No events will be queued until uvc_status_start() is called. ++ * The barrier is needed to make sure that flush_status is visible to ++ * uvc_ctrl_status_event_work() when uvc_status_start() will be called ++ * again. ++ */ ++ smp_store_release(&dev->flush_status, false); + } +--- a/drivers/media/usb/uvc/uvcvideo.h ++++ b/drivers/media/usb/uvc/uvcvideo.h +@@ -603,6 +603,7 @@ struct uvc_device { + /* Status Interrupt Endpoint */ + struct usb_host_endpoint *int_ep; + struct urb *int_urb; ++ bool flush_status; + u8 *status; + struct input_dev *input; + char input_phys[64]; diff --git a/queue-4.19/media-uvcvideo-provide-sync-and-async-uvc_ctrl_status_event.patch b/queue-4.19/media-uvcvideo-provide-sync-and-async-uvc_ctrl_status_event.patch new file mode 100644 index 00000000000..0137d19eeb9 --- /dev/null +++ b/queue-4.19/media-uvcvideo-provide-sync-and-async-uvc_ctrl_status_event.patch @@ -0,0 +1,107 @@ +From d9c8763e61295be0a21dc04ad9c379d5d17c3d86 Mon Sep 17 00:00:00 2001 +From: Ricardo Ribalda +Date: Wed, 23 Dec 2020 14:35:20 +0100 +Subject: media: uvcvideo: Provide sync and async uvc_ctrl_status_event + +From: Ricardo Ribalda + +commit d9c8763e61295be0a21dc04ad9c379d5d17c3d86 upstream. + +Split the functionality of void uvc_ctrl_status_event_work in two, so it +can be called by functions outside interrupt context and not part of an +URB. + +Signed-off-by: Ricardo Ribalda +Signed-off-by: Laurent Pinchart +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/uvc/uvc_ctrl.c | 25 +++++++++++++++---------- + drivers/media/usb/uvc/uvc_status.c | 3 ++- + drivers/media/usb/uvc/uvcvideo.h | 4 +++- + 3 files changed, 20 insertions(+), 12 deletions(-) + +--- a/drivers/media/usb/uvc/uvc_ctrl.c ++++ b/drivers/media/usb/uvc/uvc_ctrl.c +@@ -1280,17 +1280,12 @@ static void uvc_ctrl_send_slave_event(st + uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes); + } + +-static void uvc_ctrl_status_event_work(struct work_struct *work) ++void uvc_ctrl_status_event(struct uvc_video_chain *chain, ++ struct uvc_control *ctrl, const u8 *data) + { +- struct uvc_device *dev = container_of(work, struct uvc_device, +- async_ctrl.work); +- struct uvc_ctrl_work *w = &dev->async_ctrl; +- struct uvc_video_chain *chain = w->chain; + struct uvc_control_mapping *mapping; +- struct uvc_control *ctrl = w->ctrl; + struct uvc_fh *handle; + unsigned int i; +- int ret; + + mutex_lock(&chain->ctrl_mutex); + +@@ -1298,7 +1293,7 @@ static void uvc_ctrl_status_event_work(s + ctrl->handle = NULL; + + list_for_each_entry(mapping, &ctrl->info.mappings, list) { +- s32 value = __uvc_ctrl_get_value(mapping, w->data); ++ s32 value = __uvc_ctrl_get_value(mapping, data); + + /* + * handle may be NULL here if the device sends auto-update +@@ -1317,6 +1312,16 @@ static void uvc_ctrl_status_event_work(s + } + + mutex_unlock(&chain->ctrl_mutex); ++} ++ ++static void uvc_ctrl_status_event_work(struct work_struct *work) ++{ ++ struct uvc_device *dev = container_of(work, struct uvc_device, ++ async_ctrl.work); ++ struct uvc_ctrl_work *w = &dev->async_ctrl; ++ int ret; ++ ++ uvc_ctrl_status_event(w->chain, w->ctrl, w->data); + + /* Resubmit the URB. */ + w->urb->interval = dev->int_ep->desc.bInterval; +@@ -1326,8 +1331,8 @@ static void uvc_ctrl_status_event_work(s + ret); + } + +-bool uvc_ctrl_status_event(struct urb *urb, struct uvc_video_chain *chain, +- struct uvc_control *ctrl, const u8 *data) ++bool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain, ++ struct uvc_control *ctrl, const u8 *data) + { + struct uvc_device *dev = chain->dev; + struct uvc_ctrl_work *w = &dev->async_ctrl; +--- a/drivers/media/usb/uvc/uvc_status.c ++++ b/drivers/media/usb/uvc/uvc_status.c +@@ -184,7 +184,8 @@ static bool uvc_event_control(struct urb + + switch (status->bAttribute) { + case UVC_CTRL_VALUE_CHANGE: +- return uvc_ctrl_status_event(urb, chain, ctrl, status->bValue); ++ return uvc_ctrl_status_event_async(urb, chain, ctrl, ++ status->bValue); + + case UVC_CTRL_INFO_CHANGE: + case UVC_CTRL_FAILURE_CHANGE: +--- a/drivers/media/usb/uvc/uvcvideo.h ++++ b/drivers/media/usb/uvc/uvcvideo.h +@@ -768,7 +768,9 @@ int uvc_ctrl_add_mapping(struct uvc_vide + int uvc_ctrl_init_device(struct uvc_device *dev); + void uvc_ctrl_cleanup_device(struct uvc_device *dev); + int uvc_ctrl_restore_values(struct uvc_device *dev); +-bool uvc_ctrl_status_event(struct urb *urb, struct uvc_video_chain *chain, ++bool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain, ++ struct uvc_control *ctrl, const u8 *data); ++void uvc_ctrl_status_event(struct uvc_video_chain *chain, + struct uvc_control *ctrl, const u8 *data); + + int uvc_ctrl_begin(struct uvc_video_chain *chain); diff --git a/queue-4.19/series b/queue-4.19/series index 6a1ad2b6bb4..5f43703cdb5 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -246,3 +246,7 @@ bluetooth-hci_sock-purge-socket-queues-in-the-destruct-callback.patch s390-maccess-add-no-dat-mode-to-kernel_write.patch s390-setup-init-jump-labels-before-command-line-parsing.patch tcp-fix-listen-regression-in-5.15.88.patch +media-uvcvideo-provide-sync-and-async-uvc_ctrl_status_event.patch +media-uvcvideo-fix-race-condition-with-usb_kill_urb.patch +f2fs-fix-cgroup-writeback-accounting-with-fs-layer-encryption.patch +thermal-intel-powerclamp-fix-cur_state-for-multi-package-system.patch diff --git a/queue-4.19/thermal-intel-powerclamp-fix-cur_state-for-multi-package-system.patch b/queue-4.19/thermal-intel-powerclamp-fix-cur_state-for-multi-package-system.patch new file mode 100644 index 00000000000..cebf62d4df5 --- /dev/null +++ b/queue-4.19/thermal-intel-powerclamp-fix-cur_state-for-multi-package-system.patch @@ -0,0 +1,97 @@ +From 8e47363588377e1bdb65e2b020b409cfb44dd260 Mon Sep 17 00:00:00 2001 +From: Srinivas Pandruvada +Date: Wed, 1 Feb 2023 12:39:41 -0800 +Subject: thermal: intel: powerclamp: Fix cur_state for multi package system + +From: Srinivas Pandruvada + +commit 8e47363588377e1bdb65e2b020b409cfb44dd260 upstream. + +The powerclamp cooling device cur_state shows actual idle observed by +package C-state idle counters. But the implementation is not sufficient +for multi package or multi die system. The cur_state value is incorrect. +On these systems, these counters must be read from each package/die and +somehow aggregate them. But there is no good method for aggregation. + +It was not a problem when explicit CPU model addition was required to +enable intel powerclamp. In this way certain CPU models could have +been avoided. But with the removal of CPU model check with the +availability of Package C-state counters, the driver is loaded on most +of the recent systems. + +For multi package/die systems, just show the actual target idle state, +the system is trying to achieve. In powerclamp this is the user set +state minus one. + +Also there is no use of starting a worker thread for polling package +C-state counters and applying any compensation for multiple package +or multiple die systems. + +Fixes: b721ca0d1927 ("thermal/powerclamp: remove cpu whitelist") +Signed-off-by: Srinivas Pandruvada +Cc: 4.14+ # 4.14+ +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thermal/intel_powerclamp.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +--- a/drivers/thermal/intel_powerclamp.c ++++ b/drivers/thermal/intel_powerclamp.c +@@ -72,6 +72,7 @@ + + static unsigned int target_mwait; + static struct dentry *debug_dir; ++static bool poll_pkg_cstate_enable; + + /* user selected target */ + static unsigned int set_target_ratio; +@@ -280,6 +281,9 @@ static unsigned int get_compensation(int + { + unsigned int comp = 0; + ++ if (!poll_pkg_cstate_enable) ++ return 0; ++ + /* we only use compensation if all adjacent ones are good */ + if (ratio == 1 && + cal_data[ratio].confidence >= CONFIDENCE_OK && +@@ -552,7 +556,8 @@ static int start_power_clamp(void) + control_cpu = cpumask_first(cpu_online_mask); + + clamping = true; +- schedule_delayed_work(&poll_pkg_cstate_work, 0); ++ if (poll_pkg_cstate_enable) ++ schedule_delayed_work(&poll_pkg_cstate_work, 0); + + /* start one kthread worker per online cpu */ + for_each_online_cpu(cpu) { +@@ -621,11 +626,15 @@ static int powerclamp_get_max_state(stru + static int powerclamp_get_cur_state(struct thermal_cooling_device *cdev, + unsigned long *state) + { +- if (true == clamping) +- *state = pkg_cstate_ratio_cur; +- else ++ if (clamping) { ++ if (poll_pkg_cstate_enable) ++ *state = pkg_cstate_ratio_cur; ++ else ++ *state = set_target_ratio; ++ } else { + /* to save power, do not poll idle ratio while not clamping */ + *state = -1; /* indicates invalid state */ ++ } + + return 0; + } +@@ -770,6 +779,9 @@ static int __init powerclamp_init(void) + goto exit_unregister; + } + ++ if (topology_max_packages() == 1) ++ poll_pkg_cstate_enable = true; ++ + cooling_dev = thermal_cooling_device_register("intel_powerclamp", NULL, + &powerclamp_cooling_ops); + if (IS_ERR(cooling_dev)) {