Hello!
I'm using Asus Vivobook Laptop. Which fails to resume by timer set by timerfd_settime function call. It simply ignores the timer and keeps sleeping until I press any key. When key pressed notebook wakes up and treating key resume event as timer event.
I tested this using systemd and its HibernateDelaySec option, which allows to wake system during the sleep by timer to switch to hibernate state replacing suspend mode. During suspend notebook simply do nothing when timer hits, and when I press any key it wakes, and went to hibernate (treating key pressing wake event as timer event). Systemd has checks which should prevent hibernating if system wakes by key press, but those checks does not fails. I tested the same suspend / hibernate software on desktop - everything working fine.
This systemd code responsible for suspend / timer / hibernate logic:
tfd = timerfd_create(CLOCK_BOOTTIME_ALARM, TFD_NONBLOCK|TFD_CLOEXEC);
timerfd_settime(tfd, 0, &ts, NULL)
execute(sleep_config, SLEEP_HYBRID_SLEEP, NULL)
fd_wait_for_event(tfd, POLLIN, 0)
woken_by_timer = FLAGS_SET(r, POLLIN)
check_wakeup_type()
Basically it is POSIX calls responsible for setting timer alarms set and reading timer status.
I've tested on recent debian kernel Linux 6.1.0-10-amd64 and stable release from kernel.org Linux 6.4.7 - same behavior.
It most likely hardware/EFI or kernel issue.
Full logs:
https://linux-hardware.org/?probe=d1a4b2769ahttps://bugzilla.kernel.org/show_bug.cgi?id=217728
-- AK
Currently the KernelAllocator simply passes the size of the type Layout
to krealloc(), and in theory the alignment requirement from the type
Layout may be larger than the guarantee provided by SLAB, which means
the allocated object is mis-aligned.
Fixes this by adjusting the allocation size to the nearest power of two,
which SLAB always guarantees a size-aligned allocation. And because Rust
guarantees that original size must be a multiple of alignment and the
alignment must be a power of two, then the alignment requirement is
satisfied.
Suggested-by: Vlastimil Babka <vbabka(a)suse.cz>
Co-developed-by: Andreas Hindborg (Samsung) <nmi(a)metaspace.dk>
Signed-off-by: Andreas Hindborg (Samsung) <nmi(a)metaspace.dk>
Signed-off-by: Boqun Feng <boqun.feng(a)gmail.com>
Cc: stable(a)vger.kernel.org # v6.1+
---
Some more explanation:
* Layout is a data structure describing a particular memory layout,
conceptionally it has two fields: align and size.
* align is guaranteed to be a power of two.
* size can be smaller than align (only when the Layout is created via
Layout::from_align_size())
* After pad_to_align(), the size is guaranteed to be a multiple of
align
For more information, please see:
https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html
rust/bindings/bindings_helper.h | 1 +
rust/kernel/allocator.rs | 17 ++++++++++++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index 3e601ce2548d..6619ce95dd37 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -15,3 +15,4 @@
/* `bindgen` gets confused at certain things. */
const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL;
const gfp_t BINDINGS___GFP_ZERO = __GFP_ZERO;
+const size_t BINDINGS_ARCH_SLAB_MINALIGN = ARCH_SLAB_MINALIGN;
diff --git a/rust/kernel/allocator.rs b/rust/kernel/allocator.rs
index 397a3dd57a9b..66575cf87ce2 100644
--- a/rust/kernel/allocator.rs
+++ b/rust/kernel/allocator.rs
@@ -11,9 +11,24 @@
unsafe impl GlobalAlloc for KernelAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+ // Customized layouts from `Layout::from_size_align()` can have size < align, so pads first.
+ let layout = layout.pad_to_align();
+
+ let mut size = layout.size();
+
+ if layout.align() > bindings::BINDINGS_ARCH_SLAB_MINALIGN {
+ // The alignment requirement exceeds the slab guarantee, then tries to enlarges the size
+ // to use the "power-of-two" size/alignment guarantee (see comments in kmalloc() for
+ // more information).
+ //
+ // Note that `layout.size()` (after padding) is guaranteed to be muliples of
+ // `layout.align()`, so `next_power_of_two` gives enough alignment guarantee.
+ size = size.next_power_of_two();
+ }
+
// `krealloc()` is used instead of `kmalloc()` because the latter is
// an inline function and cannot be bound to as a result.
- unsafe { bindings::krealloc(ptr::null(), layout.size(), bindings::GFP_KERNEL) as *mut u8 }
+ unsafe { bindings::krealloc(ptr::null(), size, bindings::GFP_KERNEL) as *mut u8 }
}
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
--
2.39.2
damos_new_filter() is returning a damos_filter struct without
initializing its ->list field. And the users of the function uses the
struct without initializing the field. As a result, uninitialized
memory access error is possible. Actually, a kernel NULL pointer
dereference BUG can be triggered using DAMON user-space tool, like
below.
# damo start --damos_action stat --damos_filter anon matching
# damo tune --damos_action stat --damos_filter anon matching --damos_filter anon nomatching
# dmesg
[...]
[ 36.908136] BUG: kernel NULL pointer dereference, address: 0000000000000008
[ 36.910483] #PF: supervisor write access in kernel mode
[ 36.912238] #PF: error_code(0x0002) - not-present page
[ 36.913415] PGD 0 P4D 0
[ 36.913978] Oops: 0002 [#1] PREEMPT SMP PTI
[ 36.914878] CPU: 32 PID: 1335 Comm: kdamond.0 Not tainted 6.5.0-rc3-mm-unstable-damon+ #1
[ 36.916621] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
[ 36.919051] RIP: 0010:damos_destroy_filter (include/linux/list.h:114 include/linux/list.h:137 include/linux/list.h:148 mm/damon/core.c:345 mm/damon/core.c:355)
[...]
[ 36.938247] Call Trace:
[ 36.938721] <TASK>
[...]
[ 36.950064] ? damos_destroy_filter (include/linux/list.h:114 include/linux/list.h:137 include/linux/list.h:148 mm/damon/core.c:345 mm/damon/core.c:355)
[ 36.950883] ? damon_sysfs_set_scheme_filters.isra.0 (mm/damon/sysfs-schemes.c:1573)
[ 36.952019] damon_sysfs_set_schemes (mm/damon/sysfs-schemes.c:1674 mm/damon/sysfs-schemes.c:1686)
[ 36.952875] damon_sysfs_apply_inputs (mm/damon/sysfs.c:1312 mm/damon/sysfs.c:1298)
[ 36.953757] ? damon_pa_check_accesses (mm/damon/paddr.c:168 mm/damon/paddr.c:179)
[ 36.954648] damon_sysfs_cmd_request_callback (mm/damon/sysfs.c:1329 mm/damon/sysfs.c:1359)
[...]
The first patch of this patchset fixes the bug by initializing the field in
damos_new_filter(). The second patch adds a unit test for the problem.
Note that the second patch Cc stable@ without Fixes: tag, since it would
be better to be ingested together for avoiding any future regression.
SeongJae Park (2):
mm/damon/core: initialize damo_filter->list from damos_new_filter()
mm/damon/core-test: add a test for damos_new_filter()
mm/damon/core-test.h | 13 +++++++++++++
mm/damon/core.c | 1 +
2 files changed, 14 insertions(+)
--
2.25.1
The stuttering code isn't functioning as expected. Ideally, it should
pause the torture threads for a designated period before resuming. Yet,
it fails to halt the test for the correct duration. Additionally, a race
condition exists, potentially causing the stuttering code to pause for
an extended period if the 'spt' variable is non-zero due to the stutter
orchestration thread's inadequate CPU time.
Moreover, over-stuttering can hinder RCU's progress on TREE07 kernels.
This happens as the stuttering code may run within a softirq due to RCU
callbacks. Consequently, ksoftirqd keeps a CPU busy for several seconds,
thus obstructing RCU's progress. This situation triggers a warning
message in the logs:
[ 2169.481783] rcu_torture_writer: rtort_pipe_count: 9
This warning suggests that an RCU torture object, although invisible to
RCU readers, couldn't make it past the pipe array and be freed -- a
strong indication that there weren't enough grace periods during the
stutter interval.
To address these issues, this patch sets the "stutter end" time to an
absolute point in the future set by the main stutter thread. This is
then used for waiting in stutter_wait(). While the stutter thread still
defines this absolute time, the waiters' waiting logic doesn't rely on
the stutter thread receiving sufficient CPU time to halt the stuttering
as the halting is now self-controlled.
Cc: stable(a)vger.kernel.org
Signed-off-by: Joel Fernandes (Google) <joel(a)joelfernandes.org>
---
kernel/torture.c | 45 ++++++++++++---------------------------------
1 file changed, 12 insertions(+), 33 deletions(-)
diff --git a/kernel/torture.c b/kernel/torture.c
index 6ba62e5993e7..fd353f98162f 100644
--- a/kernel/torture.c
+++ b/kernel/torture.c
@@ -720,7 +720,7 @@ static void torture_shutdown_cleanup(void)
* suddenly applied to or removed from the system.
*/
static struct task_struct *stutter_task;
-static int stutter_pause_test;
+static ktime_t stutter_till_abs_time;
static int stutter;
static int stutter_gap;
@@ -730,30 +730,16 @@ static int stutter_gap;
*/
bool stutter_wait(const char *title)
{
- unsigned int i = 0;
bool ret = false;
- int spt;
+ ktime_t till_ns;
cond_resched_tasks_rcu_qs();
- spt = READ_ONCE(stutter_pause_test);
- for (; spt; spt = READ_ONCE(stutter_pause_test)) {
- if (!ret && !rt_task(current)) {
- sched_set_normal(current, MAX_NICE);
- ret = true;
- }
- if (spt == 1) {
- torture_hrtimeout_jiffies(1, NULL);
- } else if (spt == 2) {
- while (READ_ONCE(stutter_pause_test)) {
- if (!(i++ & 0xffff))
- torture_hrtimeout_us(10, 0, NULL);
- cond_resched();
- }
- } else {
- torture_hrtimeout_jiffies(round_jiffies_relative(HZ), NULL);
- }
- torture_shutdown_absorb(title);
+ till_ns = READ_ONCE(stutter_till_abs_time);
+ if (till_ns && ktime_before(ktime_get(), till_ns)) {
+ torture_hrtimeout_ns(till_ns, 0, HRTIMER_MODE_ABS, NULL);
+ ret = true;
}
+ torture_shutdown_absorb(title);
return ret;
}
EXPORT_SYMBOL_GPL(stutter_wait);
@@ -764,23 +750,16 @@ EXPORT_SYMBOL_GPL(stutter_wait);
*/
static int torture_stutter(void *arg)
{
- DEFINE_TORTURE_RANDOM(rand);
- int wtime;
+ ktime_t till_ns;
VERBOSE_TOROUT_STRING("torture_stutter task started");
do {
if (!torture_must_stop() && stutter > 1) {
- wtime = stutter;
- if (stutter > 2) {
- WRITE_ONCE(stutter_pause_test, 1);
- wtime = stutter - 3;
- torture_hrtimeout_jiffies(wtime, &rand);
- wtime = 2;
- }
- WRITE_ONCE(stutter_pause_test, 2);
- torture_hrtimeout_jiffies(wtime, NULL);
+ till_ns = ktime_add_ns(ktime_get(),
+ jiffies_to_nsecs(stutter));
+ WRITE_ONCE(stutter_till_abs_time, till_ns);
+ torture_hrtimeout_jiffies(stutter - 1, NULL);
}
- WRITE_ONCE(stutter_pause_test, 0);
if (!torture_must_stop())
torture_hrtimeout_jiffies(stutter_gap, NULL);
torture_shutdown_absorb("torture_stutter");
--
2.41.0.487.g6d72f3e995-goog
Add a 200ms delay after sending a ctrl report to Quadro,
Octo, D5 Next and Aquaero to give them enough time to
process the request and save the data to memory. Otherwise,
under heavier userspace loads where multiple sysfs entries
are usually set in quick succession, a new ctrl report could
be requested from the device while it's still processing the
previous one and fail with -EPIPE.
Reported by a user on Github [1] and tested by both of us.
[1] https://github.com/aleksamagicka/aquacomputer_d5next-hwmon/issues/82
Cc: stable(a)vger.kernel.org
Signed-off-by: Aleksa Savic <savicaleksa83(a)gmail.com>
---
drivers/hwmon/aquacomputer_d5next.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c
index a997dbcb563f..9cb55d51185a 100644
--- a/drivers/hwmon/aquacomputer_d5next.c
+++ b/drivers/hwmon/aquacomputer_d5next.c
@@ -652,6 +652,31 @@ static int aqc_send_ctrl_data(struct aqc_data *priv)
ret = hid_hw_raw_request(priv->hdev, priv->secondary_ctrl_report_id,
priv->secondary_ctrl_report, priv->secondary_ctrl_report_size,
HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * Wait 200ms before returning to make sure that the device actually processed both reports
+ * and saved ctrl data to memory. Otherwise, an aqc_get_ctrl_data() call made shortly after
+ * may fail with -EPIPE because the device is still busy and can't provide data. This can
+ * happen when userspace tools, such as fancontrol or liquidctl, write to sysfs entries in
+ * quick succession.
+ *
+ * 200ms was found to be the sweet spot between fixing the issue and not significantly
+ * prolonging the call. Quadro, Octo, D5 Next and Aquaero are currently known to be
+ * affected.
+ */
+ switch (priv->kind) {
+ case quadro:
+ case octo:
+ case d5next:
+ case aquaero:
+ msleep(200);
+ break;
+ default:
+ break;
+ }
+
return ret;
}
--
2.41.0
There are some bugfix for the HNS3 ethernet driver
Jian Shen (1):
net: hns3: restore user pause configure when disable autoneg
Jie Wang (2):
net: hns3: refactor hclge_mac_link_status_wait for interface reuse
net: hns3: add wait until mac link down
Peiyang Wang (1):
net: hns3: fix wrong print link down up
Yonglong Liu (2):
net: hns3: fix side effects passed to min_t()
net: hns3: fix deadlock issue when externel_lb and reset are executed
together
.../net/ethernet/hisilicon/hns3/hns3_enet.c | 17 ++++++++--
.../hisilicon/hns3/hns3pf/hclge_main.c | 32 ++++++++++++++-----
.../ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 2 +-
.../ethernet/hisilicon/hns3/hns3pf/hclge_tm.h | 1 +
4 files changed, 41 insertions(+), 11 deletions(-)
--
2.30.0