From 01e4a515e44c9dc9c2a174fe4f24e55869ec118f Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Mon, 9 Sep 2024 08:47:29 -0400 Subject: [PATCH] Fixes for 5.4 Signed-off-by: Sasha Levin --- ...eferences-to-superblock-parameters-e.patch | 109 +++++ ...nprintf-in-show-functions-with-sysfs.patch | 383 ++++++++++++++++++ ...me-ring_buffer_read-to-read_buffer_i.patch | 133 ++++++ queue-5.4/series | 4 + ...ssible-softlockup-in-tracing_iter_re.patch | 45 ++ 5 files changed, 674 insertions(+) create mode 100644 queue-5.4/nilfs2-protect-references-to-superblock-parameters-e.patch create mode 100644 queue-5.4/nilfs2-replace-snprintf-in-show-functions-with-sysfs.patch create mode 100644 queue-5.4/ring-buffer-rename-ring_buffer_read-to-read_buffer_i.patch create mode 100644 queue-5.4/tracing-avoid-possible-softlockup-in-tracing_iter_re.patch diff --git a/queue-5.4/nilfs2-protect-references-to-superblock-parameters-e.patch b/queue-5.4/nilfs2-protect-references-to-superblock-parameters-e.patch new file mode 100644 index 00000000000..139b5d9b3f4 --- /dev/null +++ b/queue-5.4/nilfs2-protect-references-to-superblock-parameters-e.patch @@ -0,0 +1,109 @@ +From 7a3f8ea8b5fd76a922fac57eae85209320721b94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 11 Aug 2024 19:03:20 +0900 +Subject: nilfs2: protect references to superblock parameters exposed in sysfs + +From: Ryusuke Konishi + +[ Upstream commit 683408258917541bdb294cd717c210a04381931e ] + +The superblock buffers of nilfs2 can not only be overwritten at runtime +for modifications/repairs, but they are also regularly swapped, replaced +during resizing, and even abandoned when degrading to one side due to +backing device issues. So, accessing them requires mutual exclusion using +the reader/writer semaphore "nilfs->ns_sem". + +Some sysfs attribute show methods read this superblock buffer without the +necessary mutual exclusion, which can cause problems with pointer +dereferencing and memory access, so fix it. + +Link: https://lkml.kernel.org/r/20240811100320.9913-1-konishi.ryusuke@gmail.com +Fixes: da7141fb78db ("nilfs2: add /sys/fs/nilfs2/ group") +Signed-off-by: Ryusuke Konishi +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + fs/nilfs2/sysfs.c | 43 +++++++++++++++++++++++++++++++++---------- + 1 file changed, 33 insertions(+), 10 deletions(-) + +diff --git a/fs/nilfs2/sysfs.c b/fs/nilfs2/sysfs.c +index 63ab8f9e6db3..64ea44be0a64 100644 +--- a/fs/nilfs2/sysfs.c ++++ b/fs/nilfs2/sysfs.c +@@ -843,9 +843,15 @@ ssize_t nilfs_dev_revision_show(struct nilfs_dev_attr *attr, + struct the_nilfs *nilfs, + char *buf) + { +- struct nilfs_super_block **sbp = nilfs->ns_sbp; +- u32 major = le32_to_cpu(sbp[0]->s_rev_level); +- u16 minor = le16_to_cpu(sbp[0]->s_minor_rev_level); ++ struct nilfs_super_block *raw_sb; ++ u32 major; ++ u16 minor; ++ ++ down_read(&nilfs->ns_sem); ++ raw_sb = nilfs->ns_sbp[0]; ++ major = le32_to_cpu(raw_sb->s_rev_level); ++ minor = le16_to_cpu(raw_sb->s_minor_rev_level); ++ up_read(&nilfs->ns_sem); + + return sysfs_emit(buf, "%d.%d\n", major, minor); + } +@@ -863,8 +869,13 @@ ssize_t nilfs_dev_device_size_show(struct nilfs_dev_attr *attr, + struct the_nilfs *nilfs, + char *buf) + { +- struct nilfs_super_block **sbp = nilfs->ns_sbp; +- u64 dev_size = le64_to_cpu(sbp[0]->s_dev_size); ++ struct nilfs_super_block *raw_sb; ++ u64 dev_size; ++ ++ down_read(&nilfs->ns_sem); ++ raw_sb = nilfs->ns_sbp[0]; ++ dev_size = le64_to_cpu(raw_sb->s_dev_size); ++ up_read(&nilfs->ns_sem); + + return sysfs_emit(buf, "%llu\n", dev_size); + } +@@ -886,9 +897,15 @@ ssize_t nilfs_dev_uuid_show(struct nilfs_dev_attr *attr, + struct the_nilfs *nilfs, + char *buf) + { +- struct nilfs_super_block **sbp = nilfs->ns_sbp; ++ struct nilfs_super_block *raw_sb; ++ ssize_t len; + +- return sysfs_emit(buf, "%pUb\n", sbp[0]->s_uuid); ++ down_read(&nilfs->ns_sem); ++ raw_sb = nilfs->ns_sbp[0]; ++ len = sysfs_emit(buf, "%pUb\n", raw_sb->s_uuid); ++ up_read(&nilfs->ns_sem); ++ ++ return len; + } + + static +@@ -896,10 +913,16 @@ ssize_t nilfs_dev_volume_name_show(struct nilfs_dev_attr *attr, + struct the_nilfs *nilfs, + char *buf) + { +- struct nilfs_super_block **sbp = nilfs->ns_sbp; ++ struct nilfs_super_block *raw_sb; ++ ssize_t len; ++ ++ down_read(&nilfs->ns_sem); ++ raw_sb = nilfs->ns_sbp[0]; ++ len = scnprintf(buf, sizeof(raw_sb->s_volume_name), "%s\n", ++ raw_sb->s_volume_name); ++ up_read(&nilfs->ns_sem); + +- return scnprintf(buf, sizeof(sbp[0]->s_volume_name), "%s\n", +- sbp[0]->s_volume_name); ++ return len; + } + + static const char dev_readme_str[] = +-- +2.43.0 + diff --git a/queue-5.4/nilfs2-replace-snprintf-in-show-functions-with-sysfs.patch b/queue-5.4/nilfs2-replace-snprintf-in-show-functions-with-sysfs.patch new file mode 100644 index 00000000000..6eae8bb1db8 --- /dev/null +++ b/queue-5.4/nilfs2-replace-snprintf-in-show-functions-with-sysfs.patch @@ -0,0 +1,383 @@ +From 2780e7cf78baef3c76b4001817dbbe7c92b4f92e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Nov 2021 18:34:58 -0800 +Subject: nilfs2: replace snprintf in show functions with sysfs_emit + +From: Qing Wang + +[ Upstream commit 3bcd6c5bd483287f4a09d3d59a012d47677b6edc ] + +Patch series "nilfs2 updates". + +This patch (of 2): + +coccicheck complains about the use of snprintf() in sysfs show functions. + +Fix the coccicheck warning: + + WARNING: use scnprintf or sprintf. + +Use sysfs_emit instead of scnprintf or sprintf makes more sense. + +Link: https://lkml.kernel.org/r/1635151862-11547-1-git-send-email-konishi.ryusuke@gmail.com +Link: https://lkml.kernel.org/r/1634095759-4625-1-git-send-email-wangqing@vivo.com +Link: https://lkml.kernel.org/r/1635151862-11547-2-git-send-email-konishi.ryusuke@gmail.com +Signed-off-by: Qing Wang +Signed-off-by: Ryusuke Konishi +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Stable-dep-of: 683408258917 ("nilfs2: protect references to superblock parameters exposed in sysfs") +Signed-off-by: Sasha Levin +--- + fs/nilfs2/sysfs.c | 76 +++++++++++++++++++++++------------------------ + 1 file changed, 38 insertions(+), 38 deletions(-) + +diff --git a/fs/nilfs2/sysfs.c b/fs/nilfs2/sysfs.c +index 57afd06db62d..63ab8f9e6db3 100644 +--- a/fs/nilfs2/sysfs.c ++++ b/fs/nilfs2/sysfs.c +@@ -108,7 +108,7 @@ static ssize_t + nilfs_snapshot_inodes_count_show(struct nilfs_snapshot_attr *attr, + struct nilfs_root *root, char *buf) + { +- return snprintf(buf, PAGE_SIZE, "%llu\n", ++ return sysfs_emit(buf, "%llu\n", + (unsigned long long)atomic64_read(&root->inodes_count)); + } + +@@ -116,7 +116,7 @@ static ssize_t + nilfs_snapshot_blocks_count_show(struct nilfs_snapshot_attr *attr, + struct nilfs_root *root, char *buf) + { +- return snprintf(buf, PAGE_SIZE, "%llu\n", ++ return sysfs_emit(buf, "%llu\n", + (unsigned long long)atomic64_read(&root->blocks_count)); + } + +@@ -129,7 +129,7 @@ static ssize_t + nilfs_snapshot_README_show(struct nilfs_snapshot_attr *attr, + struct nilfs_root *root, char *buf) + { +- return snprintf(buf, PAGE_SIZE, snapshot_readme_str); ++ return sysfs_emit(buf, snapshot_readme_str); + } + + NILFS_SNAPSHOT_RO_ATTR(inodes_count); +@@ -230,7 +230,7 @@ static ssize_t + nilfs_mounted_snapshots_README_show(struct nilfs_mounted_snapshots_attr *attr, + struct the_nilfs *nilfs, char *buf) + { +- return snprintf(buf, PAGE_SIZE, mounted_snapshots_readme_str); ++ return sysfs_emit(buf, mounted_snapshots_readme_str); + } + + NILFS_MOUNTED_SNAPSHOTS_RO_ATTR(README); +@@ -268,7 +268,7 @@ nilfs_checkpoints_checkpoints_number_show(struct nilfs_checkpoints_attr *attr, + + ncheckpoints = cpstat.cs_ncps; + +- return snprintf(buf, PAGE_SIZE, "%llu\n", ncheckpoints); ++ return sysfs_emit(buf, "%llu\n", ncheckpoints); + } + + static ssize_t +@@ -291,7 +291,7 @@ nilfs_checkpoints_snapshots_number_show(struct nilfs_checkpoints_attr *attr, + + nsnapshots = cpstat.cs_nsss; + +- return snprintf(buf, PAGE_SIZE, "%llu\n", nsnapshots); ++ return sysfs_emit(buf, "%llu\n", nsnapshots); + } + + static ssize_t +@@ -305,7 +305,7 @@ nilfs_checkpoints_last_seg_checkpoint_show(struct nilfs_checkpoints_attr *attr, + last_cno = nilfs->ns_last_cno; + spin_unlock(&nilfs->ns_last_segment_lock); + +- return snprintf(buf, PAGE_SIZE, "%llu\n", last_cno); ++ return sysfs_emit(buf, "%llu\n", last_cno); + } + + static ssize_t +@@ -319,7 +319,7 @@ nilfs_checkpoints_next_checkpoint_show(struct nilfs_checkpoints_attr *attr, + cno = nilfs->ns_cno; + up_read(&nilfs->ns_segctor_sem); + +- return snprintf(buf, PAGE_SIZE, "%llu\n", cno); ++ return sysfs_emit(buf, "%llu\n", cno); + } + + static const char checkpoints_readme_str[] = +@@ -335,7 +335,7 @@ static ssize_t + nilfs_checkpoints_README_show(struct nilfs_checkpoints_attr *attr, + struct the_nilfs *nilfs, char *buf) + { +- return snprintf(buf, PAGE_SIZE, checkpoints_readme_str); ++ return sysfs_emit(buf, checkpoints_readme_str); + } + + NILFS_CHECKPOINTS_RO_ATTR(checkpoints_number); +@@ -366,7 +366,7 @@ nilfs_segments_segments_number_show(struct nilfs_segments_attr *attr, + struct the_nilfs *nilfs, + char *buf) + { +- return snprintf(buf, PAGE_SIZE, "%lu\n", nilfs->ns_nsegments); ++ return sysfs_emit(buf, "%lu\n", nilfs->ns_nsegments); + } + + static ssize_t +@@ -374,7 +374,7 @@ nilfs_segments_blocks_per_segment_show(struct nilfs_segments_attr *attr, + struct the_nilfs *nilfs, + char *buf) + { +- return snprintf(buf, PAGE_SIZE, "%lu\n", nilfs->ns_blocks_per_segment); ++ return sysfs_emit(buf, "%lu\n", nilfs->ns_blocks_per_segment); + } + + static ssize_t +@@ -388,7 +388,7 @@ nilfs_segments_clean_segments_show(struct nilfs_segments_attr *attr, + ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile); + up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); + +- return snprintf(buf, PAGE_SIZE, "%lu\n", ncleansegs); ++ return sysfs_emit(buf, "%lu\n", ncleansegs); + } + + static ssize_t +@@ -408,7 +408,7 @@ nilfs_segments_dirty_segments_show(struct nilfs_segments_attr *attr, + return err; + } + +- return snprintf(buf, PAGE_SIZE, "%llu\n", sustat.ss_ndirtysegs); ++ return sysfs_emit(buf, "%llu\n", sustat.ss_ndirtysegs); + } + + static const char segments_readme_str[] = +@@ -424,7 +424,7 @@ nilfs_segments_README_show(struct nilfs_segments_attr *attr, + struct the_nilfs *nilfs, + char *buf) + { +- return snprintf(buf, PAGE_SIZE, segments_readme_str); ++ return sysfs_emit(buf, segments_readme_str); + } + + NILFS_SEGMENTS_RO_ATTR(segments_number); +@@ -461,7 +461,7 @@ nilfs_segctor_last_pseg_block_show(struct nilfs_segctor_attr *attr, + last_pseg = nilfs->ns_last_pseg; + spin_unlock(&nilfs->ns_last_segment_lock); + +- return snprintf(buf, PAGE_SIZE, "%llu\n", ++ return sysfs_emit(buf, "%llu\n", + (unsigned long long)last_pseg); + } + +@@ -476,7 +476,7 @@ nilfs_segctor_last_seg_sequence_show(struct nilfs_segctor_attr *attr, + last_seq = nilfs->ns_last_seq; + spin_unlock(&nilfs->ns_last_segment_lock); + +- return snprintf(buf, PAGE_SIZE, "%llu\n", last_seq); ++ return sysfs_emit(buf, "%llu\n", last_seq); + } + + static ssize_t +@@ -490,7 +490,7 @@ nilfs_segctor_last_seg_checkpoint_show(struct nilfs_segctor_attr *attr, + last_cno = nilfs->ns_last_cno; + spin_unlock(&nilfs->ns_last_segment_lock); + +- return snprintf(buf, PAGE_SIZE, "%llu\n", last_cno); ++ return sysfs_emit(buf, "%llu\n", last_cno); + } + + static ssize_t +@@ -504,7 +504,7 @@ nilfs_segctor_current_seg_sequence_show(struct nilfs_segctor_attr *attr, + seg_seq = nilfs->ns_seg_seq; + up_read(&nilfs->ns_segctor_sem); + +- return snprintf(buf, PAGE_SIZE, "%llu\n", seg_seq); ++ return sysfs_emit(buf, "%llu\n", seg_seq); + } + + static ssize_t +@@ -518,7 +518,7 @@ nilfs_segctor_current_last_full_seg_show(struct nilfs_segctor_attr *attr, + segnum = nilfs->ns_segnum; + up_read(&nilfs->ns_segctor_sem); + +- return snprintf(buf, PAGE_SIZE, "%llu\n", segnum); ++ return sysfs_emit(buf, "%llu\n", segnum); + } + + static ssize_t +@@ -532,7 +532,7 @@ nilfs_segctor_next_full_seg_show(struct nilfs_segctor_attr *attr, + nextnum = nilfs->ns_nextnum; + up_read(&nilfs->ns_segctor_sem); + +- return snprintf(buf, PAGE_SIZE, "%llu\n", nextnum); ++ return sysfs_emit(buf, "%llu\n", nextnum); + } + + static ssize_t +@@ -546,7 +546,7 @@ nilfs_segctor_next_pseg_offset_show(struct nilfs_segctor_attr *attr, + pseg_offset = nilfs->ns_pseg_offset; + up_read(&nilfs->ns_segctor_sem); + +- return snprintf(buf, PAGE_SIZE, "%lu\n", pseg_offset); ++ return sysfs_emit(buf, "%lu\n", pseg_offset); + } + + static ssize_t +@@ -560,7 +560,7 @@ nilfs_segctor_next_checkpoint_show(struct nilfs_segctor_attr *attr, + cno = nilfs->ns_cno; + up_read(&nilfs->ns_segctor_sem); + +- return snprintf(buf, PAGE_SIZE, "%llu\n", cno); ++ return sysfs_emit(buf, "%llu\n", cno); + } + + static ssize_t +@@ -588,7 +588,7 @@ nilfs_segctor_last_seg_write_time_secs_show(struct nilfs_segctor_attr *attr, + ctime = nilfs->ns_ctime; + up_read(&nilfs->ns_segctor_sem); + +- return snprintf(buf, PAGE_SIZE, "%llu\n", ctime); ++ return sysfs_emit(buf, "%llu\n", ctime); + } + + static ssize_t +@@ -616,7 +616,7 @@ nilfs_segctor_last_nongc_write_time_secs_show(struct nilfs_segctor_attr *attr, + nongc_ctime = nilfs->ns_nongc_ctime; + up_read(&nilfs->ns_segctor_sem); + +- return snprintf(buf, PAGE_SIZE, "%llu\n", nongc_ctime); ++ return sysfs_emit(buf, "%llu\n", nongc_ctime); + } + + static ssize_t +@@ -630,7 +630,7 @@ nilfs_segctor_dirty_data_blocks_count_show(struct nilfs_segctor_attr *attr, + ndirtyblks = atomic_read(&nilfs->ns_ndirtyblks); + up_read(&nilfs->ns_segctor_sem); + +- return snprintf(buf, PAGE_SIZE, "%u\n", ndirtyblks); ++ return sysfs_emit(buf, "%u\n", ndirtyblks); + } + + static const char segctor_readme_str[] = +@@ -667,7 +667,7 @@ static ssize_t + nilfs_segctor_README_show(struct nilfs_segctor_attr *attr, + struct the_nilfs *nilfs, char *buf) + { +- return snprintf(buf, PAGE_SIZE, segctor_readme_str); ++ return sysfs_emit(buf, segctor_readme_str); + } + + NILFS_SEGCTOR_RO_ATTR(last_pseg_block); +@@ -736,7 +736,7 @@ nilfs_superblock_sb_write_time_secs_show(struct nilfs_superblock_attr *attr, + sbwtime = nilfs->ns_sbwtime; + up_read(&nilfs->ns_sem); + +- return snprintf(buf, PAGE_SIZE, "%llu\n", sbwtime); ++ return sysfs_emit(buf, "%llu\n", sbwtime); + } + + static ssize_t +@@ -750,7 +750,7 @@ nilfs_superblock_sb_write_count_show(struct nilfs_superblock_attr *attr, + sbwcount = nilfs->ns_sbwcount; + up_read(&nilfs->ns_sem); + +- return snprintf(buf, PAGE_SIZE, "%u\n", sbwcount); ++ return sysfs_emit(buf, "%u\n", sbwcount); + } + + static ssize_t +@@ -764,7 +764,7 @@ nilfs_superblock_sb_update_frequency_show(struct nilfs_superblock_attr *attr, + sb_update_freq = nilfs->ns_sb_update_freq; + up_read(&nilfs->ns_sem); + +- return snprintf(buf, PAGE_SIZE, "%u\n", sb_update_freq); ++ return sysfs_emit(buf, "%u\n", sb_update_freq); + } + + static ssize_t +@@ -812,7 +812,7 @@ static ssize_t + nilfs_superblock_README_show(struct nilfs_superblock_attr *attr, + struct the_nilfs *nilfs, char *buf) + { +- return snprintf(buf, PAGE_SIZE, sb_readme_str); ++ return sysfs_emit(buf, sb_readme_str); + } + + NILFS_SUPERBLOCK_RO_ATTR(sb_write_time); +@@ -847,7 +847,7 @@ ssize_t nilfs_dev_revision_show(struct nilfs_dev_attr *attr, + u32 major = le32_to_cpu(sbp[0]->s_rev_level); + u16 minor = le16_to_cpu(sbp[0]->s_minor_rev_level); + +- return snprintf(buf, PAGE_SIZE, "%d.%d\n", major, minor); ++ return sysfs_emit(buf, "%d.%d\n", major, minor); + } + + static +@@ -855,7 +855,7 @@ ssize_t nilfs_dev_blocksize_show(struct nilfs_dev_attr *attr, + struct the_nilfs *nilfs, + char *buf) + { +- return snprintf(buf, PAGE_SIZE, "%u\n", nilfs->ns_blocksize); ++ return sysfs_emit(buf, "%u\n", nilfs->ns_blocksize); + } + + static +@@ -866,7 +866,7 @@ ssize_t nilfs_dev_device_size_show(struct nilfs_dev_attr *attr, + struct nilfs_super_block **sbp = nilfs->ns_sbp; + u64 dev_size = le64_to_cpu(sbp[0]->s_dev_size); + +- return snprintf(buf, PAGE_SIZE, "%llu\n", dev_size); ++ return sysfs_emit(buf, "%llu\n", dev_size); + } + + static +@@ -877,7 +877,7 @@ ssize_t nilfs_dev_free_blocks_show(struct nilfs_dev_attr *attr, + sector_t free_blocks = 0; + + nilfs_count_free_blocks(nilfs, &free_blocks); +- return snprintf(buf, PAGE_SIZE, "%llu\n", ++ return sysfs_emit(buf, "%llu\n", + (unsigned long long)free_blocks); + } + +@@ -888,7 +888,7 @@ ssize_t nilfs_dev_uuid_show(struct nilfs_dev_attr *attr, + { + struct nilfs_super_block **sbp = nilfs->ns_sbp; + +- return snprintf(buf, PAGE_SIZE, "%pUb\n", sbp[0]->s_uuid); ++ return sysfs_emit(buf, "%pUb\n", sbp[0]->s_uuid); + } + + static +@@ -916,7 +916,7 @@ static ssize_t nilfs_dev_README_show(struct nilfs_dev_attr *attr, + struct the_nilfs *nilfs, + char *buf) + { +- return snprintf(buf, PAGE_SIZE, dev_readme_str); ++ return sysfs_emit(buf, dev_readme_str); + } + + NILFS_DEV_RO_ATTR(revision); +@@ -1060,7 +1060,7 @@ void nilfs_sysfs_delete_device_group(struct the_nilfs *nilfs) + static ssize_t nilfs_feature_revision_show(struct kobject *kobj, + struct attribute *attr, char *buf) + { +- return snprintf(buf, PAGE_SIZE, "%d.%d\n", ++ return sysfs_emit(buf, "%d.%d\n", + NILFS_CURRENT_REV, NILFS_MINOR_REV); + } + +@@ -1073,7 +1073,7 @@ static ssize_t nilfs_feature_README_show(struct kobject *kobj, + struct attribute *attr, + char *buf) + { +- return snprintf(buf, PAGE_SIZE, features_readme_str); ++ return sysfs_emit(buf, features_readme_str); + } + + NILFS_FEATURE_RO_ATTR(revision); +-- +2.43.0 + diff --git a/queue-5.4/ring-buffer-rename-ring_buffer_read-to-read_buffer_i.patch b/queue-5.4/ring-buffer-rename-ring_buffer_read-to-read_buffer_i.patch new file mode 100644 index 00000000000..a6ff3f90144 --- /dev/null +++ b/queue-5.4/ring-buffer-rename-ring_buffer_read-to-read_buffer_i.patch @@ -0,0 +1,133 @@ +From 99baea6b77a586f5aba060d16b4dd2ab0712ea26 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Mar 2020 17:32:25 -0400 +Subject: ring-buffer: Rename ring_buffer_read() to read_buffer_iter_advance() + +From: Steven Rostedt (VMware) + +[ Upstream commit bc1a72afdc4a91844928831cac85731566e03bc6 ] + +When the ring buffer was first created, the iterator followed the normal +producer/consumer operations where it had both a peek() operation, that just +returned the event at the current location, and a read(), that would return +the event at the current location and also increment the iterator such that +the next peek() or read() will return the next event. + +The only use of the ring_buffer_read() is currently to move the iterator to +the next location and nothing now actually reads the event it returns. +Rename this function to its actual use case to ring_buffer_iter_advance(), +which also adds the "iter" part to the name, which is more meaningful. As +the timestamp returned by ring_buffer_read() was never used, there's no +reason that this new version should bother having returning it. It will also +become a void function. + +Link: http://lkml.kernel.org/r/20200317213416.018928618@goodmis.org + +Signed-off-by: Steven Rostedt (VMware) +Stable-dep-of: 49aa8a1f4d68 ("tracing: Avoid possible softlockup in tracing_iter_reset()") +Signed-off-by: Sasha Levin +--- + include/linux/ring_buffer.h | 3 +-- + kernel/trace/ring_buffer.c | 23 ++++++----------------- + kernel/trace/trace.c | 4 ++-- + kernel/trace/trace_functions_graph.c | 2 +- + 4 files changed, 10 insertions(+), 22 deletions(-) + +diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h +index b73950772299..12492c8a22b3 100644 +--- a/include/linux/ring_buffer.h ++++ b/include/linux/ring_buffer.h +@@ -135,8 +135,7 @@ void ring_buffer_read_finish(struct ring_buffer_iter *iter); + + struct ring_buffer_event * + ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts); +-struct ring_buffer_event * +-ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts); ++void ring_buffer_iter_advance(struct ring_buffer_iter *iter); + void ring_buffer_iter_reset(struct ring_buffer_iter *iter); + int ring_buffer_iter_empty(struct ring_buffer_iter *iter); + +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index ad97515cd5a1..2011219c11a9 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -4495,35 +4495,24 @@ ring_buffer_read_finish(struct ring_buffer_iter *iter) + EXPORT_SYMBOL_GPL(ring_buffer_read_finish); + + /** +- * ring_buffer_read - read the next item in the ring buffer by the iterator ++ * ring_buffer_iter_advance - advance the iterator to the next location + * @iter: The ring buffer iterator +- * @ts: The time stamp of the event read. + * +- * This reads the next event in the ring buffer and increments the iterator. ++ * Move the location of the iterator such that the next read will ++ * be the next location of the iterator. + */ +-struct ring_buffer_event * +-ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts) ++void ring_buffer_iter_advance(struct ring_buffer_iter *iter) + { +- struct ring_buffer_event *event; + struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer; + unsigned long flags; + + raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); +- again: +- event = rb_iter_peek(iter, ts); +- if (!event) +- goto out; +- +- if (event->type_len == RINGBUF_TYPE_PADDING) +- goto again; + + rb_advance_iter(iter); +- out: +- raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); + +- return event; ++ raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); + } +-EXPORT_SYMBOL_GPL(ring_buffer_read); ++EXPORT_SYMBOL_GPL(ring_buffer_iter_advance); + + /** + * ring_buffer_size - return the size of the ring buffer (in bytes) +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 6fd7dca57dd9..8bf28d482abe 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -3326,7 +3326,7 @@ static void trace_iterator_increment(struct trace_iterator *iter) + + iter->idx++; + if (buf_iter) +- ring_buffer_read(buf_iter, NULL); ++ ring_buffer_iter_advance(buf_iter); + } + + static struct trace_entry * +@@ -3486,7 +3486,7 @@ void tracing_iter_reset(struct trace_iterator *iter, int cpu) + if (ts >= iter->trace_buffer->time_start) + break; + entries++; +- ring_buffer_read(buf_iter, NULL); ++ ring_buffer_iter_advance(buf_iter); + } + + per_cpu_ptr(iter->trace_buffer->data, cpu)->skipped_entries = entries; +diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c +index 78af97163147..f577c11720a4 100644 +--- a/kernel/trace/trace_functions_graph.c ++++ b/kernel/trace/trace_functions_graph.c +@@ -482,7 +482,7 @@ get_return_for_leaf(struct trace_iterator *iter, + + /* this is a leaf, now advance the iterator */ + if (ring_iter) +- ring_buffer_read(ring_iter, NULL); ++ ring_buffer_iter_advance(ring_iter); + + return next; + } +-- +2.43.0 + diff --git a/queue-5.4/series b/queue-5.4/series index 30744c96fde..ded9177da2d 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -93,3 +93,7 @@ of-irq-prevent-device-address-out-of-bounds-read-in-.patch lib-generic-radix-tree.c-fix-rare-race-in-__genradix.patch ata-pata_macio-use-warn-instead-of-bug.patch nfsv4-add-missing-rescheduling-points-in-nfs_client_.patch +ring-buffer-rename-ring_buffer_read-to-read_buffer_i.patch +tracing-avoid-possible-softlockup-in-tracing_iter_re.patch +nilfs2-replace-snprintf-in-show-functions-with-sysfs.patch +nilfs2-protect-references-to-superblock-parameters-e.patch diff --git a/queue-5.4/tracing-avoid-possible-softlockup-in-tracing_iter_re.patch b/queue-5.4/tracing-avoid-possible-softlockup-in-tracing_iter_re.patch new file mode 100644 index 00000000000..2f6e4c714d5 --- /dev/null +++ b/queue-5.4/tracing-avoid-possible-softlockup-in-tracing_iter_re.patch @@ -0,0 +1,45 @@ +From 1e92fdd6cfad29f0069ecdd9c4934806fadd1b22 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Aug 2024 20:46:54 +0800 +Subject: tracing: Avoid possible softlockup in tracing_iter_reset() + +From: Zheng Yejian + +[ Upstream commit 49aa8a1f4d6800721c7971ed383078257f12e8f9 ] + +In __tracing_open(), when max latency tracers took place on the cpu, +the time start of its buffer would be updated, then event entries with +timestamps being earlier than start of the buffer would be skipped +(see tracing_iter_reset()). + +Softlockup will occur if the kernel is non-preemptible and too many +entries were skipped in the loop that reset every cpu buffer, so add +cond_resched() to avoid it. + +Cc: stable@vger.kernel.org +Fixes: 2f26ebd549b9a ("tracing: use timestamp to determine start of latency traces") +Link: https://lore.kernel.org/20240827124654.3817443-1-zhengyejian@huaweicloud.com +Suggested-by: Steven Rostedt +Signed-off-by: Zheng Yejian +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Sasha Levin +--- + kernel/trace/trace.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 8bf28d482abe..67466563d86f 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -3487,6 +3487,8 @@ void tracing_iter_reset(struct trace_iterator *iter, int cpu) + break; + entries++; + ring_buffer_iter_advance(buf_iter); ++ /* This could be a big loop */ ++ cond_resched(); + } + + per_cpu_ptr(iter->trace_buffer->data, cpu)->skipped_entries = entries; +-- +2.43.0 + -- 2.47.3