* Forwarded: [syz test] net/sched: taprio: reject too-small software schedule intervals
2025-07-28 23:27 [syzbot] [kernfs?] [mm?] INFO: rcu detected stall in kernfs_fop_open (7) syzbot
@ 2026-08-11 13:42 ` syzbot
2026-08-31 8:40 ` [syzbot] [kernfs?] [mm?] INFO: rcu detected stall in kernfs_fop_open (7) Junjie Cao
2026-09-01 1:41 ` [syzbot] [kernfs?] [mm?] " Junjie Cao
2 siblings, 0 replies; 6+ messages in thread
From: syzbot @ 2026-08-11 13:42 UTC (permalink / raw)
To: linux-kernel, syzkaller-bugs
For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.
***
Subject: [syz test] net/sched: taprio: reject too-small software schedule intervals
Author: junjie.cao@linux.dev
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git dd057113ac7ba5bdd2aed3d9405305911152f911
Signed-off-by: Junjie Cao <junjie.cao@intel.com>
diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
index 299234a5f0fe..f740918a3b17 100644
--- a/net/sched/sch_taprio.c
+++ b/net/sched/sch_taprio.c
@@ -259,6 +259,27 @@ static int length_to_duration(struct taprio_sched *q, int len)
return div_u64(len * atomic64_read(&q->picos_per_byte), PSEC_PER_NSEC);
}
+/* Software schedules service one hrtimer expiry per entry; an interval
+ * shorter than the expiry servicing cost rearms the timer in the past
+ * and storms the CPU. 100us stays above that cost across configurations
+ * (sub-us with lockdep, more under KASAN) and below any practical
+ * schedule.
+ */
+#define TAPRIO_MIN_SW_INTERVAL_NS (100 * NSEC_PER_USEC)
+
+static s64 taprio_min_interval(struct taprio_sched *q)
+{
+ s64 min_interval = length_to_duration(q, ETH_ZLEN);
+
+ /* Only pure software schedules arm the per-entry hrtimer. */
+ if (!FULL_OFFLOAD_IS_ENABLED(q->flags) &&
+ !TXTIME_ASSIST_IS_ENABLED(q->flags))
+ min_interval = max_t(s64, min_interval,
+ TAPRIO_MIN_SW_INTERVAL_NS);
+
+ return min_interval;
+}
+
static int duration_to_length(struct taprio_sched *q, u64 duration)
{
return div_u64(duration * PSEC_PER_NSEC, atomic64_read(&q->picos_per_byte));
@@ -1038,7 +1059,7 @@ static int fill_sched_entry(struct taprio_sched *q, struct nlattr **tb,
struct sched_entry *entry,
struct netlink_ext_ack *extack)
{
- int min_duration = length_to_duration(q, ETH_ZLEN);
+ s64 min_duration = taprio_min_interval(q);
u32 interval = 0;
if (tb[TCA_TAPRIO_SCHED_ENTRY_CMD])
@@ -1166,7 +1187,7 @@ static int parse_taprio_schedule(struct taprio_sched *q, struct nlattr **tb,
new->cycle_time = cycle;
}
- if (new->cycle_time < new->num_entries * length_to_duration(q, ETH_ZLEN)) {
+ if (new->cycle_time < (s64)new->num_entries * taprio_min_interval(q)) {
NL_SET_ERR_MSG(extack, "'cycle_time' is too small");
return -EINVAL;
}
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [syzbot] [kernfs?] [mm?] INFO: rcu detected stall in kernfs_fop_open (7)
2025-07-28 23:27 [syzbot] [kernfs?] [mm?] INFO: rcu detected stall in kernfs_fop_open (7) syzbot
2026-08-11 13:42 ` Forwarded: [syz test] net/sched: taprio: reject too-small software schedule intervals syzbot
@ 2026-08-31 8:40 ` Junjie Cao
2026-08-31 9:20 ` [syzbot] [kernfs?] " syzbot
2026-09-01 1:41 ` [syzbot] [kernfs?] [mm?] " Junjie Cao
2 siblings, 1 reply; 6+ messages in thread
From: Junjie Cao @ 2026-08-31 8:40 UTC (permalink / raw)
To: syzbot+19d01f6082ec61dd45b2
Cc: gregkh, tj, linux-mm, linux-kernel, syzkaller-bugs, akpm, davem,
edumazet, kuba, pabeni, horms, jhs, jiri, vinicius.gomes
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git a8455260b2e9c024d1872ac1c094793d55a7e537
diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
index 39ac5b97aa3a..901dfd2484e1 100644
--- a/net/sched/sch_taprio.c
+++ b/net/sched/sch_taprio.c
@@ -83,6 +83,10 @@ struct sched_gate_list {
s64 cycle_time;
s64 cycle_time_extension;
s64 base_time;
+ /* min(cycle_time, sum of intervals): the software schedule restarts
+ * the list after the last entry even when cycle_time is not up yet.
+ */
+ s64 period;
};
struct taprio_sched {
@@ -871,12 +875,13 @@ static struct sk_buff *taprio_dequeue(struct Qdisc *sch)
}
static bool should_restart_cycle(const struct sched_gate_list *oper,
- const struct sched_entry *entry)
+ const struct sched_entry *entry,
+ ktime_t end_time)
{
if (list_is_last(&entry->list, &oper->entries))
return true;
- if (ktime_compare(entry->end_time, oper->cycle_end_time) == 0)
+ if (ktime_compare(end_time, oper->cycle_end_time) == 0)
return true;
return false;
@@ -925,8 +930,9 @@ static enum hrtimer_restart advance_sched(struct hrtimer *timer)
int num_tc = netdev_get_num_tc(dev);
struct sched_entry *entry, *next;
struct Qdisc *sch = q->root;
- ktime_t end_time;
- int tc;
+ ktime_t end_time, next_start, now;
+ int budget, tc;
+ s64 behind;
spin_lock(&q->current_entry_lock);
entry = rcu_dereference_protected(q->current_entry,
@@ -952,23 +958,49 @@ static enum hrtimer_restart advance_sched(struct hrtimer *timer)
goto first_run;
}
- if (should_restart_cycle(oper, entry)) {
- next = list_first_entry(&oper->entries, struct sched_entry,
- list);
- oper->cycle_end_time = ktime_add_ns(oper->cycle_end_time,
- oper->cycle_time);
- } else {
- next = list_next_entry(entry, list);
+ now = hrtimer_cb_get_time(timer);
+ end_time = entry->end_time;
+ behind = ktime_sub(now, end_time);
+
+ /* Behind, e.g. delayed timer or stepped clock: skip whole periods
+ * arithmetically and walk at most one more to the entry covering
+ * now, instead of replaying the backlog one expiry at a time. The
+ * cap bounds the walk; a leftover is picked up by the next expiry.
+ */
+ if (unlikely(behind >= oper->period)) {
+ s64 jump = div64_s64(behind, oper->period) * oper->period;
+
+ end_time = ktime_add_ns(end_time, jump);
+ oper->cycle_end_time = ktime_add_ns(oper->cycle_end_time, jump);
}
- end_time = ktime_add_ns(entry->end_time, next->interval);
- end_time = min_t(ktime_t, end_time, oper->cycle_end_time);
+ budget = 2 * oper->num_entries;
+ do {
+ if (should_restart_cycle(oper, entry, end_time)) {
+ next = list_first_entry(&oper->entries,
+ struct sched_entry, list);
+ oper->cycle_end_time = ktime_add_ns(oper->cycle_end_time,
+ oper->period);
+ } else {
+ next = list_next_entry(entry, list);
+ }
+
+ next_start = end_time;
+ end_time = ktime_add_ns(next_start, next->interval);
+ end_time = min_t(ktime_t, end_time, oper->cycle_end_time);
+ entry = next;
+ } while (unlikely(ktime_compare(end_time, now) <= 0) && budget--);
+ /* next can be the entry already published as q->current_entry (a
+ * single-entry schedule, or a catch-up of whole periods), so the
+ * close times and budgets below are rewritten in place while
+ * taprio_dequeue_from_txq() may be reading them.
+ */
for (tc = 0; tc < num_tc; tc++) {
if (next->gate_duration[tc] == oper->cycle_time)
next->gate_close_time[tc] = KTIME_MAX;
else
- next->gate_close_time[tc] = ktime_add_ns(entry->end_time,
+ next->gate_close_time[tc] = ktime_add_ns(next_start,
next->gate_duration[tc]);
}
@@ -1130,6 +1162,8 @@ static int parse_taprio_schedule(struct taprio_sched *q, struct nlattr **tb,
struct sched_gate_list *new,
struct netlink_ext_ack *extack)
{
+ struct sched_entry *entry;
+ ktime_t cycle = 0;
int err = 0;
if (tb[TCA_TAPRIO_ATTR_SCHED_SINGLE_ENTRY]) {
@@ -1152,13 +1186,10 @@ static int parse_taprio_schedule(struct taprio_sched *q, struct nlattr **tb,
if (err < 0)
return err;
- if (!new->cycle_time) {
- struct sched_entry *entry;
- ktime_t cycle = 0;
-
- list_for_each_entry(entry, &new->entries, list)
- cycle = ktime_add_ns(cycle, entry->interval);
+ list_for_each_entry(entry, &new->entries, list)
+ cycle = ktime_add_ns(cycle, entry->interval);
+ if (!new->cycle_time) {
if (cycle < 0 || cycle > INT_MAX) {
NL_SET_ERR_MSG(extack, "'cycle_time' is too big");
return -EINVAL;
@@ -1172,6 +1203,7 @@ static int parse_taprio_schedule(struct taprio_sched *q, struct nlattr **tb,
return -EINVAL;
}
+ new->period = min(new->cycle_time, cycle);
taprio_calculate_gate_durations(q, new);
return 0;
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [syzbot] [kernfs?] INFO: rcu detected stall in kernfs_fop_open (7)
2026-08-31 8:40 ` [syzbot] [kernfs?] [mm?] INFO: rcu detected stall in kernfs_fop_open (7) Junjie Cao
@ 2026-08-31 9:20 ` syzbot
0 siblings, 0 replies; 6+ messages in thread
From: syzbot @ 2026-08-31 9:20 UTC (permalink / raw)
To: akpm, davem, edumazet, gregkh, horms, jhs, jiri, junjie.cao,
kuba, linux-kernel, linux-mm, pabeni, syzkaller-bugs, tj,
vinicius.gomes
Hello,
syzbot tried to test the proposed patch but the build/boot failed:
[mem 0x000a0000-0x000bffff window]
[ 4.028875][ T1] pci_bus 0000:00: resource 7 [mem 0xc0000000-0xfebfefff window]
[ 4.033220][ T1] pci 0000:00:00.0: Limiting direct PCI/PCI transfers
[ 4.036737][ T1] PCI: CLS 0 bytes, default 64
[ 4.038432][ T1] PCI-DMA: Using software bounce buffering for IO (SWIOTLB)
[ 4.040165][ T1] software IO TLB: mapped [mem 0x00000000b4600000-0x00000000b8600000] (64MB)
[ 4.043514][ T1] ACPI: bus type thunderbolt registered
[ 4.053039][ T1] RAPL PMU: API unit is 2^-32 Joules, 0 fixed counters, 10737418240 ms ovfl timer
[ 4.056245][ T60] kworker/u8:1 (60) used greatest stack depth: 28144 bytes left
[ 4.056263][ T61] kworker/u8:1 (61) used greatest stack depth: 27696 bytes left
[ 4.087176][ T1] kvm_amd: CPU 1 isn't AMD or Hygon
[ 4.088501][ T1] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x1fb7086095e, max_idle_ns: 440795277026 ns
[ 4.091902][ T1] clocksource: Switched to clocksource tsc
[ 4.125123][ T76] kworker/u8:4 (76) used greatest stack depth: 27232 bytes left
[ 4.126234][ T80] kworker/u8:3 (80) used greatest stack depth: 26624 bytes left
[ 4.133748][ T1] Initialise system trusted keyrings
[ 4.140237][ T1] workingset: timestamp_bits=40 (anon: 35) max_order=21 bucket_order=0 (anon: 0)
[ 4.155583][ T1] DLM installed
[ 4.162423][ T1] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[ 4.174374][ T1] NFS: Registering the id_resolver key type
[ 4.174518][ T1] Key type id_resolver registered
[ 4.174528][ T1] Key type id_legacy registered
[ 4.174908][ T1] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[ 4.175092][ T1] nfs4flexfilelayout_init: NFSv4 Flexfile Layout Driver Registering...
[ 4.179203][ T1] smbdirect: subsystem loading...
[ 4.191613][ T1] smbdirect: subsystem loaded
[ 4.207305][ T1] Key type cifs.spnego registered
[ 4.207587][ T1] Key type cifs.idmap registered
[ 4.213246][ T1] ntfs3: Enabled Linux POSIX ACLs support
[ 4.213275][ T1] ntfs3: Read-only LZX/Xpress compression included
[ 4.213730][ T1] jffs2: version 2.2. (NAND) (SUMMARY) © 2001-2006 Red Hat, Inc.
[ 4.215917][ T1] romfs: ROMFS MTD (C) 2007 Red Hat, Inc.
[ 4.216209][ T1] QNX4 filesystem 0.2.3 registered.
[ 4.216310][ T1] qnx6: QNX6 filesystem 1.0.0 registered.
[ 4.218163][ T1] fuse: init (API version 7.46)
[ 4.224565][ T1] orangefs_debugfs_init: called with debug mask: :none: :0:
[ 4.225933][ T1] orangefs_init: module version upstream loaded
[ 4.227030][ T1] JFS: nTxBlock = 8192, nTxLock = 65536
[ 4.239841][ T1] SGI XFS with ACLs, security attributes, realtime, quota, no debug enabled
[ 4.248736][ T1] 9p: Installing v9fs 9p2000 file system support
[ 4.249591][ T1] NILFS version 2 loaded
[ 4.249600][ T1] befs: version: 0.9.3
[ 4.251044][ T1] ocfs2: Registered cluster interface o2cb
[ 4.253105][ T1] ocfs2: Registered cluster interface user
[ 4.263937][ T1] OCFS2 User DLM kernel interface loaded
[ 4.302028][ T1] gfs2: GFS2 installed
[ 4.325876][ T1] ceph: loaded (mds proto 32)
[ 4.350261][ T1] cryptd: max_cpu_qlen set to 1000
[ 4.387051][ T1] NET: Registered PF_ALG protocol family
[ 4.387424][ T1] async_tx: api initialized (async)
[ 4.387479][ T1] Key type asymmetric registered
[ 4.387520][ T1] Asymmetric key parser 'x509' registered
[ 4.387530][ T1] Asymmetric key parser 'pkcs8' registered
[ 4.387539][ T1] Key type pkcs7_test registered
[ 4.389176][ T1] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 239)
[ 4.391001][ T1] io scheduler mq-deadline registered
[ 4.391015][ T1] io scheduler kyber registered
[ 4.391571][ T1] io scheduler bfq registered
[ 4.392067][ T1] raid6: skipped pq benchmark and selected avx2x4
[ 4.429845][ T1] input: Power Button as /devices/platform/LNXPWRBN:00/input/input0
[ 4.434169][ T1] ACPI: button: Power Button [PWRF]
[ 4.440466][ T1] input: Sleep Button as /devices/platform/LNXSLPBN:00/input/input1
[ 4.443845][ T1] ACPI: button: Sleep Button [SLPF]
[ 4.492202][ T1] ioatdma: Intel(R) QuickData Technology Driver 5.00
[ 4.545316][ T1] ACPI: \_SB_.LNKC: Enabled at IRQ 11
[ 4.552843][ T1] virtio-pci 0000:00:03.0: virtio_pci: leaving for legacy driver
[ 4.607773][ T1] ACPI: \_SB_.LNKD: Enabled at IRQ 10
[ 4.614492][ T1] virtio-pci 0000:00:04.0: virtio_pci: leaving for legacy driver
[ 4.676585][ T1] ACPI: \_SB_.LNKB: Enabled at IRQ 10
[ 4.682990][ T1] virtio-pci 0000:00:06.0: virtio_pci: leaving for legacy driver
[ 4.727260][ T1] virtio-pci 0000:00:07.0: virtio_pci: leaving for legacy driver
[ 5.558377][ T1] N_HDLC line discipline registered with maxframe=4096
[ 5.559546][ T1] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[ 5.574119][ T1] 00:02: ttyS0 I/O:0x3f8 (irq = 4, base_baud = 115200) is a 16550A
[ 5.605595][ T1] 00:03: ttyS1 I/O:0x2f8 (irq = 3, base_baud = 115200) is a 16550A
[ 5.628064][ T1] 00:04: ttyS2 I/O:0x3e8 (irq = 6, base_baud = 115200) is a 16550A
[ 5.648098][ T1] 00:05: ttyS3 I/O:0x2e8 (irq = 7, base_baud = 115200) is a 16550A
[ 5.688220][ T1] Non-volatile memory driver v1.3
[ 5.733159][ T1] usbcore: registered new interface driver xillyusb
[ 5.735138][ T1] ACPI: bus type drm_connector registered
[ 5.748474][ T1] [drm] Initialized vgem 1.0.0 for vgem on minor 0
[ 5.756447][ T1] ------------[ cut here ]------------
[ 5.756502][ T1] [PLANE:35:plane-0] pixel format with alpha exposed but blend mode not setup
[ 5.756521][ T1] WARNING: drivers/gpu/drm/drm_mode_config.c:873 at drm_mode_config_validate+0x1c6a/0x1e60, CPU#0: swapper/0/1
[ 5.785118][ T1] Modules linked in:
[ 5.789695][ T1] CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted syzkaller #0 PREEMPT(full)
[ 5.799116][ T1] Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/24/2026
[ 5.809847][ T1] RIP: 0010:drm_mode_config_validate+0x1cab/0x1e60
[ 5.816628][ T1] Code: 0f 85 ae 00 00 00 4d 8d 77 10 8b 6d 00 4c 89 f0 48 c1 e8 03 80 3c 18 00 74 08 4c 89 f7 e8 dd b2 cc fc 49 8b 16 4c 89 ef 89 ee <67> 48 0f b9 3a eb 05 e8 89 9e 5e fc 49 bd 00 00 00 00 00 fc ff df
[ 5.838674][ T1] RSP: 0000:ffffc90000067810 EFLAGS: 00010246
[ 5.845420][ T1] RAX: 1ffff11004c8a408 RBX: dffffc0000000000 RCX: ffff88801ceaddc0
[ 5.854061][ T1] RDX: ffff888026032380 RSI: 0000000000000023 RDI: ffffffff8ff26aa0
[ 5.863036][ T1] RBP: 0000000000000023 R08: ffff8880239ccf6b R09: 1ffff110047399ed
[ 5.872017][ T1] R10: dffffc0000000000 R11: ffffed10047399ee R12: dffffc0000000000
[ 5.880270][ T1] R13: ffffffff8ff26aa0 R14: ffff888026452040 R15: ffff888026452030
[ 5.888798][ T1] FS: 0000000000000000(0000) GS:ffff888125704000(0000) knlGS:0000000000000000
[ 5.898155][ T1] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 5.905317][ T1] CR2: ffff88823ffff000 CR3: 000000000e33a000 CR4: 00000000003526f0
[ 5.913991][ T1] Call Trace:
[ 5.917285][ T1] <TASK>
[ 5.920539][ T1] ? debugfs_create_file_full+0x3f/0x60
[ 5.926297][ T1] drm_dev_register+0x7c/0xd80
[ 5.931608][ T1] vkms_create+0x40d/0x4f0
[ 5.936577][ T1] ? __pfx_vkms_init+0x10/0x10
[ 5.941934][ T1] vkms_init+0x57/0x80
[ 5.946295][ T1] do_one_initcall+0x250/0x870
[ 5.951406][ T1] ? __pfx_vkms_init+0x10/0x10
[ 5.956290][ T1] ? __pfx_do_one_initcall+0x10/0x10
[ 5.962347][ T1] ? lapic_next_event+0x11/0x20
[ 5.967732][ T1] ? clockevents_program_event+0x491/0x630
[ 5.973595][ T1] ? __pfx___schedule+0x10/0x10
[ 5.978930][ T1] ? irqentry_exit+0x218/0x790
[ 5.984090][ T1] ? lockdep_hardirqs_on+0x7b/0x110
[ 5.989508][ T1] ? irqentry_exit+0x218/0x790
[ 5.994552][ T1] ? trace_irq_disable+0x3b/0x140
[ 5.999974][ T1] ? parameq+0x25/0x170
[ 6.004878][ T1] ? parameq+0x14d/0x170
[ 6.009224][ T1] ? parse_args+0x9c3/0xad0
[ 6.014154][ T1] ? rcu_is_watching+0x16/0xb0
[ 6.019426][ T1] do_initcall_level+0x10a/0x1a0
[ 6.024854][ T1] ? kernel_init+0x22/0x1d0
[ 6.029487][ T1] do_initcalls+0x59/0xa0
[ 6.034077][ T1] kernel_init_freeable+0x29d/0x3e0
[ 6.039941][ T1] ? __pfx_kernel_init+0x10/0x10
[ 6.045132][ T1] kernel_init+0x22/0x1d0
[ 6.049797][ T1] ? __pfx_kernel_init+0x10/0x10
[ 6.055569][ T1] ret_from_fork+0x514/0xb70
[ 6.060573][ T1] ? __pfx_ret_from_fork+0x10/0x10
[ 6.066057][ T1] ? __switch_to+0xc89/0x1420
[ 6.071718][ T1] ? __pfx_kernel_init+0x10/0x10
[ 6.077617][ T1] ret_from_fork_asm+0x1a/0x30
[ 6.082852][ T1] </TASK>
[ 6.086082][ T1] Kernel panic - not syncing: kernel: panic_on_warn set ...
[ 6.092792][ T1] CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted syzkaller #0 PREEMPT(full)
[ 6.092792][ T1] Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/24/2026
[ 6.092792][ T1] Call Trace:
[ 6.092792][ T1] <TASK>
[ 6.092792][ T1] vpanic+0x56d/0xa60
[ 6.092792][ T1] ? __pfx__printk+0x10/0x10
[ 6.092792][ T1] ? __pfx_vpanic+0x10/0x10
[ 6.092792][ T1] ? is_bpf_text_address+0x292/0x2b0
[ 6.092792][ T1] ? is_bpf_text_address+0x26/0x2b0
[ 6.140129][ T1] panic+0xc5/0xd0
[ 6.140129][ T1] ? __pfx_panic+0x10/0x10
[ 6.140129][ T1] ? ret_from_fork_asm+0x1a/0x30
[ 6.140129][ T1] __warn+0x315/0x4c0
[ 6.140129][ T1] ? drm_mode_config_validate+0x1c6a/0x1e60
[ 6.140129][ T1] ? drm_mode_config_validate+0x1c6a/0x1e60
[ 6.140129][ T1] __report_bug+0x276/0x570
[ 6.140129][ T1] ? look_up_lock_class+0x57/0x110
[ 6.140129][ T1] ? drm_mode_config_validate+0x1c6a/0x1e60
[ 6.140129][ T1] ? __pfx___report_bug+0x10/0x10
[ 6.140129][ T1] ? __pfx_inode_set_ctime_to_ts+0x10/0x10
[ 6.140129][ T1] ? seqcount_lockdep_reader_access+0xeb/0x100
[ 6.140129][ T1] ? ktime_get_coarse_real_ts64_mg+0x1be/0x1e0
[ 6.140129][ T1] report_bug_entry+0x19b/0x290
[ 6.140129][ T1] ? drm_mode_config_validate+0x1cab/0x1e60
[ 6.140129][ T1] ? drm_mode_config_validate+0x1cb0/0x1e60
[ 6.140129][ T1] handle_bug+0xce/0x200
[ 6.140129][ T1] exc_invalid_op+0x1a/0x50
[ 6.240148][ T1] asm_exc_invalid_op+0x1a/0x20
[ 6.240148][ T1] RIP: 0010:drm_mode_config_validate+0x1cab/0x1e60
[ 6.240148][ T1] Code: 0f 85 ae 00 00 00 4d 8d 77 10 8b 6d 00 4c 89 f0 48 c1 e8 03 80 3c 18 00 74 08 4c 89 f7 e8 dd b2 cc fc 49 8b 16 4c 89 ef 89 ee <67> 48 0f b9 3a eb 05 e8 89 9e 5e fc 49 bd 00 00 00 00 00 fc ff df
[ 6.240148][ T1] RSP: 0000:ffffc90000067810 EFLAGS: 00010246
[ 6.240148][ T1] RAX: 1ffff11004c8a408 RBX: dffffc0000000000 RCX: ffff88801ceaddc0
[ 6.240148][ T1] RDX: ffff888026032380 RSI: 0000000000000023 RDI: ffffffff8ff26aa0
[ 6.240148][ T1] RBP: 0000000000000023 R08: ffff8880239ccf6b R09: 1ffff110047399ed
[ 6.240148][ T1] R10: dffffc0000000000 R11: ffffed10047399ee R12: dffffc0000000000
[ 6.240148][ T1] R13: ffffffff8ff26aa0 R14: ffff888026452040 R15: ffff888026452030
[ 6.240148][ T1] ? debugfs_create_file_full+0x3f/0x60
[ 6.240148][ T1] drm_dev_register+0x7c/0xd80
[ 6.240148][ T1] vkms_create+0x40d/0x4f0
[ 6.340134][ T1] ? __pfx_vkms_init+0x10/0x10
[ 6.340134][ T1] vkms_init+0x57/0x80
[ 6.340134][ T1] do_one_initcall+0x250/0x870
[ 6.340134][ T1] ? __pfx_vkms_init+0x10/0x10
[ 6.340134][ T1] ? __pfx_do_one_initcall+0x10/0x10
[ 6.340134][ T1] ? lapic_next_event+0x11/0x20
[ 6.340134][ T1] ? clockevents_program_event+0x491/0x630
[ 6.340134][ T1] ? __pfx___schedule+0x10/0x10
[ 6.340134][ T1] ? irqentry_exit+0x218/0x790
[ 6.340134][ T1] ? lockdep_hardirqs_on+0x7b/0x110
[ 6.340134][ T1] ? irqentry_exit+0x218/0x790
[ 6.340134][ T1] ? trace_irq_disable+0x3b/0x140
[ 6.340134][ T1] ? parameq+0x25/0x170
[ 6.340134][ T1] ? parameq+0x14d/0x170
[ 6.340134][ T1] ? parse_args+0x9c3/0xad0
[ 6.340134][ T1] ? rcu_is_watching+0x16/0xb0
[ 6.340134][ T1] do_initcall_level+0x10a/0x1a0
[ 6.440160][ T1] ? kernel_init+0x22/0x1d0
[ 6.440160][ T1] do_initcalls+0x59/0xa0
[ 6.440160][ T1] kernel_init_freeable+0x29d/0x3e0
[ 6.440160][ T1] ? __pfx_kernel_init+0x10/0x10
[ 6.440160][ T1] kernel_init+0x22/0x1d0
[ 6.440160][ T1] ? __pfx_kernel_init+0x10/0x10
[ 6.440160][ T1] ret_from_fork+0x514/0xb70
[ 6.440160][ T1] ? __pfx_ret_from_fork+0x10/0x10
[ 6.440160][ T1] ? __switch_to+0xc89/0x1420
[ 6.440160][ T1] ? __pfx_kernel_init+0x10/0x10
[ 6.440160][ T1] ret_from_fork_asm+0x1a/0x30
[ 6.440160][ T1] </TASK>
[ 6.440160][ T1] Kernel Offset: disabled
[ 6.440160][ T1] Rebooting in 86400 seconds..
syzkaller build log:
go env (err=<nil>)
AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE='auto'
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/syzkaller/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/syzkaller/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build106592319=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/syzkaller/jobs-2/linux/gopath/src/github.com/google/syzkaller/go.mod'
GOMODCACHE='/syzkaller/jobs-2/linux/gopath/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/syzkaller/jobs-2/linux/gopath'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/syzkaller/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.26.0'
GOWORK=''
PKG_CONFIG='pkg-config'
git status (err=<nil>)
HEAD detached at fb8f743dc82
nothing to commit, working tree clean
tput: No value for $TERM and no -T specified
tput: No value for $TERM and no -T specified
Makefile:31: run command via tools/syz-env for best compatibility, see:
Makefile:32: https://github.com/google/syzkaller/blob/master/docs/contributing.md#using-syz-env
go list -f '{{.Stale}}' ./sys/syz-sysgen | grep -q false || go install ./sys/syz-sysgen
make .descriptions
tput: No value for $TERM and no -T specified
tput: No value for $TERM and no -T specified
Makefile:31: run command via tools/syz-env for best compatibility, see:
Makefile:32: https://github.com/google/syzkaller/blob/master/docs/contributing.md#using-syz-env
bin/syz-sysgen
touch .descriptions
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w -X github.com/google/syzkaller/prog.GitRevision=fb8f743dc82ba3a879228aa71ce09fdc570665d1 -X github.com/google/syzkaller/prog.gitRevisionDate=20250724-140804" -o ./bin/linux_amd64/syz-execprog github.com/google/syzkaller/tools/syz-execprog
mkdir -p ./bin/linux_amd64
g++ -o ./bin/linux_amd64/syz-executor executor/executor.cc \
-m64 -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=16384 -Wno-stringop-overflow -Wno-array-bounds -Wno-format-overflow -Wno-unused-but-set-variable -Wno-unused-command-line-argument -static-pie -std=c++17 -I. -Iexecutor/_include -DGOOS_linux=1 -DGOARCH_amd64=1 \
-DHOSTGOOS_linux=1 -DGIT_REVISION=\"fb8f743dc82ba3a879228aa71ce09fdc570665d1\"
/usr/bin/ld: /tmp/ccAow3F6.o: in function `Connection::Connect(char const*, char const*)':
executor.cc:(.text._ZN10Connection7ConnectEPKcS1_[_ZN10Connection7ConnectEPKcS1_]+0x386): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
Error text is too large and was truncated, full error text is at:
https://syzkaller.appspot.com/x/error.txt?x=16824349580000
Tested on:
commit: a8455260 ipvlan: unregister upper devices outside pnod..
git tree: git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
kernel config: https://syzkaller.appspot.com/x/.config?x=d7588e5a39260ad2
dashboard link: https://syzkaller.appspot.com/bug?extid=19d01f6082ec61dd45b2
compiler: Debian clang version 22.1.8 (++20260613092233+e80beda6e255-1~exp1~20260613092250.77), Debian LLD 22.1.8
patch: https://syzkaller.appspot.com/x/patch.diff?x=170c4349580000
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [syzbot] [kernfs?] [mm?] INFO: rcu detected stall in kernfs_fop_open (7)
2025-07-28 23:27 [syzbot] [kernfs?] [mm?] INFO: rcu detected stall in kernfs_fop_open (7) syzbot
2026-08-11 13:42 ` Forwarded: [syz test] net/sched: taprio: reject too-small software schedule intervals syzbot
2026-08-31 8:40 ` [syzbot] [kernfs?] [mm?] INFO: rcu detected stall in kernfs_fop_open (7) Junjie Cao
@ 2026-09-01 1:41 ` Junjie Cao
2026-09-01 7:45 ` [syzbot] [kernfs?] " syzbot
2 siblings, 1 reply; 6+ messages in thread
From: Junjie Cao @ 2026-09-01 1:41 UTC (permalink / raw)
To: syzbot+19d01f6082ec61dd45b2
Cc: gregkh, tj, linux-mm, linux-kernel, syzkaller-bugs, akpm, davem,
edumazet, kuba, pabeni, horms, jhs, jiri, vinicius.gomes
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git abdf623ddb75b24659018d3952d8f61937306ae5
diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
index 39ac5b97aa3a..901dfd2484e1 100644
--- a/net/sched/sch_taprio.c
+++ b/net/sched/sch_taprio.c
@@ -83,6 +83,10 @@ struct sched_gate_list {
s64 cycle_time;
s64 cycle_time_extension;
s64 base_time;
+ /* min(cycle_time, sum of intervals): the software schedule restarts
+ * the list after the last entry even when cycle_time is not up yet.
+ */
+ s64 period;
};
struct taprio_sched {
@@ -871,12 +875,13 @@ static struct sk_buff *taprio_dequeue(struct Qdisc *sch)
}
static bool should_restart_cycle(const struct sched_gate_list *oper,
- const struct sched_entry *entry)
+ const struct sched_entry *entry,
+ ktime_t end_time)
{
if (list_is_last(&entry->list, &oper->entries))
return true;
- if (ktime_compare(entry->end_time, oper->cycle_end_time) == 0)
+ if (ktime_compare(end_time, oper->cycle_end_time) == 0)
return true;
return false;
@@ -925,8 +930,9 @@ static enum hrtimer_restart advance_sched(struct hrtimer *timer)
int num_tc = netdev_get_num_tc(dev);
struct sched_entry *entry, *next;
struct Qdisc *sch = q->root;
- ktime_t end_time;
- int tc;
+ ktime_t end_time, next_start, now;
+ int budget, tc;
+ s64 behind;
spin_lock(&q->current_entry_lock);
entry = rcu_dereference_protected(q->current_entry,
@@ -952,23 +958,49 @@ static enum hrtimer_restart advance_sched(struct hrtimer *timer)
goto first_run;
}
- if (should_restart_cycle(oper, entry)) {
- next = list_first_entry(&oper->entries, struct sched_entry,
- list);
- oper->cycle_end_time = ktime_add_ns(oper->cycle_end_time,
- oper->cycle_time);
- } else {
- next = list_next_entry(entry, list);
+ now = hrtimer_cb_get_time(timer);
+ end_time = entry->end_time;
+ behind = ktime_sub(now, end_time);
+
+ /* Behind, e.g. delayed timer or stepped clock: skip whole periods
+ * arithmetically and walk at most one more to the entry covering
+ * now, instead of replaying the backlog one expiry at a time. The
+ * cap bounds the walk; a leftover is picked up by the next expiry.
+ */
+ if (unlikely(behind >= oper->period)) {
+ s64 jump = div64_s64(behind, oper->period) * oper->period;
+
+ end_time = ktime_add_ns(end_time, jump);
+ oper->cycle_end_time = ktime_add_ns(oper->cycle_end_time, jump);
}
- end_time = ktime_add_ns(entry->end_time, next->interval);
- end_time = min_t(ktime_t, end_time, oper->cycle_end_time);
+ budget = 2 * oper->num_entries;
+ do {
+ if (should_restart_cycle(oper, entry, end_time)) {
+ next = list_first_entry(&oper->entries,
+ struct sched_entry, list);
+ oper->cycle_end_time = ktime_add_ns(oper->cycle_end_time,
+ oper->period);
+ } else {
+ next = list_next_entry(entry, list);
+ }
+
+ next_start = end_time;
+ end_time = ktime_add_ns(next_start, next->interval);
+ end_time = min_t(ktime_t, end_time, oper->cycle_end_time);
+ entry = next;
+ } while (unlikely(ktime_compare(end_time, now) <= 0) && budget--);
+ /* next can be the entry already published as q->current_entry (a
+ * single-entry schedule, or a catch-up of whole periods), so the
+ * close times and budgets below are rewritten in place while
+ * taprio_dequeue_from_txq() may be reading them.
+ */
for (tc = 0; tc < num_tc; tc++) {
if (next->gate_duration[tc] == oper->cycle_time)
next->gate_close_time[tc] = KTIME_MAX;
else
- next->gate_close_time[tc] = ktime_add_ns(entry->end_time,
+ next->gate_close_time[tc] = ktime_add_ns(next_start,
next->gate_duration[tc]);
}
@@ -1130,6 +1162,8 @@ static int parse_taprio_schedule(struct taprio_sched *q, struct nlattr **tb,
struct sched_gate_list *new,
struct netlink_ext_ack *extack)
{
+ struct sched_entry *entry;
+ ktime_t cycle = 0;
int err = 0;
if (tb[TCA_TAPRIO_ATTR_SCHED_SINGLE_ENTRY]) {
@@ -1152,13 +1186,10 @@ static int parse_taprio_schedule(struct taprio_sched *q, struct nlattr **tb,
if (err < 0)
return err;
- if (!new->cycle_time) {
- struct sched_entry *entry;
- ktime_t cycle = 0;
-
- list_for_each_entry(entry, &new->entries, list)
- cycle = ktime_add_ns(cycle, entry->interval);
+ list_for_each_entry(entry, &new->entries, list)
+ cycle = ktime_add_ns(cycle, entry->interval);
+ if (!new->cycle_time) {
if (cycle < 0 || cycle > INT_MAX) {
NL_SET_ERR_MSG(extack, "'cycle_time' is too big");
return -EINVAL;
@@ -1172,6 +1203,7 @@ static int parse_taprio_schedule(struct taprio_sched *q, struct nlattr **tb,
return -EINVAL;
}
+ new->period = min(new->cycle_time, cycle);
taprio_calculate_gate_durations(q, new);
return 0;
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [syzbot] [kernfs?] INFO: rcu detected stall in kernfs_fop_open (7)
2026-09-01 1:41 ` [syzbot] [kernfs?] [mm?] " Junjie Cao
@ 2026-09-01 7:45 ` syzbot
0 siblings, 0 replies; 6+ messages in thread
From: syzbot @ 2026-09-01 7:45 UTC (permalink / raw)
To: akpm, davem, edumazet, gregkh, horms, jhs, jiri, junjie.cao,
kuba, linux-kernel, linux-mm, pabeni, syzkaller-bugs, tj,
vinicius.gomes
Hello,
syzbot has tested the proposed patch and the reproducer did not trigger any issue:
Reported-by: syzbot+19d01f6082ec61dd45b2@syzkaller.appspotmail.com
Tested-by: syzbot+19d01f6082ec61dd45b2@syzkaller.appspotmail.com
Tested on:
commit: abdf623d Merge tag 'wq-for-7.3-rc1-fixes' of git://git..
git tree: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
console output: https://syzkaller.appspot.com/x/log.txt?x=12f51379580000
kernel config: https://syzkaller.appspot.com/x/.config?x=d7588e5a39260ad2
dashboard link: https://syzkaller.appspot.com/bug?extid=19d01f6082ec61dd45b2
compiler: Debian clang version 22.1.8 (++20260613092233+e80beda6e255-1~exp1~20260613092250.77), Debian LLD 22.1.8
patch: https://syzkaller.appspot.com/x/patch.diff?x=14a46d9e580000
Note: testing is done by a robot and is best-effort only.
^ permalink raw reply [flat|nested] 6+ messages in thread