6.10.13-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainerPATCH 269/634 selftests/bpf: Fix incorrect parameters in NULL pointer checking
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hao Ge <[email protected]>
[ Upstream commit c264487e5410e5a72db8a414566ab7d144223e6c ]
Smatch reported the following warning:
./tools/testing/selftests/bpf/testing_helpers.c:455 get_xlated_program()
warn: variable dereferenced before check 'buf' (see line 454)
It seems correct,so let's modify it based on it's suggestion.
Actually,commit b23ed4d74c4d ("selftests/bpf: Fix invalid pointer check in get_xlated_program()") fixed an issue in the test_verifier.c once,but it was reverted this time.
Let's solve this issue with the minimal changes possible.
--- tools/testing/selftests/bpf/testing_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/bpf/testing_helpers.c +1 -1
@@ -451,7 +451,7 @@ int get_xlated_program(int fd_prog, struct bpf_insn **buf, __u32 *cnt) *cnt = xlated_prog_len / buf_element_size; *buf =calloc (*cnt, buf_element_size); -if (!buf) { +if (!*buf) {perror ("can't allocate xlated program buffer" );return -ENOMEM ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 270/634 libbpf: Fix bpf_object__open_skeleton()s mishandling of options
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrii Nakryiko <[email protected]>
[ Upstream commit c634d6f4e12d00c954410ba11db45799a8c77b5b ]
We do an ugly copying of options in bpf_object__open_skeleton() just to be able to set object name from skeleton's recorded name (while still allowing user to override it through opts->object_name).
This is not just ugly, but it also is broken due to memcpy() that doesn't take into account potential skel_opts' and user-provided opts' sizes differences due to backward and forward compatibility. This leads to copying over extra bytes and then failing to validate options properly. It could, technically, lead also to SIGSEGV, if we are unlucky.
So just get rid of that memory copy completely and instead pass default object name into bpf_object_open() directly, simplifying all this significantly. The rule now is that obj_name should be non-NULL for bpf_object_open() when called with in-memory buffer, so validate that explicitly as well.
We adopt bpf_object__open_mem() to this as well and generate default name (based on buffer memory address and size) outside of bpf_object_open().
--- tools/lib/bpf/libbpf.c | 52 +++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 33 deletions(-)
tools/lib/bpf/libbpf.c +19 -33
@@ -7866,16 +7866,19 @@ static int bpf_object_init_progs(struct bpf_object *obj, const struct bpf_object }static struct bpf_object *bpf_object_open (const char *path,const void *obj_buf,size_t obj_buf_sz, +const char *obj_name,const struct bpf_object_open_opts *opts) { -const char *obj_name, *kconfig, *btf_tmp_path, *token_path; +const char *kconfig, *btf_tmp_path, *token_path;struct bpf_object *obj; -char tmp_name[64 ];int err;char *log_buf;size_t log_size;__u32 log_level; +if (obj_buf && !obj_name) +return ERR_PTR (-EINVAL ); +if (elf_version (EV_CURRENT ) ==EV_NONE ) {pr_warn ("failed to init libelf for %s\n" , path ? :"(mem buf)" );
@@ -7885,16 +7888,12 @@ static struct bpf_object *bpf_object_open(const char *path, const void *obj_buf,if (!OPTS_VALID (opts, bpf_object_open_opts))return ERR_PTR (-EINVAL ); - obj_name =OPTS_GET (opts, object_name,NULL ); + obj_name =OPTS_GET (opts, object_name,NULL ) ?: obj_name;if (obj_buf) { -if (!obj_name) { -snprintf (tmp_name,sizeof (tmp_name),"%lx-%lx" , - (unsigned long )obj_buf, - (unsigned long )obj_buf_sz); - obj_name = tmp_name; - } path = obj_name;pr_debug ("loading object '%s' from buffer\n" , obj_name); + }else { +pr_debug ("loading object from %s\n" , path); } log_buf =OPTS_GET (opts, kernel_log_buf,NULL );
@@ -7978,9 +7977,7 @@ bpf_object__open_file(const char *path, const struct bpf_object_open_opts *opts)if (!path)return libbpf_err_ptr (-EINVAL ); -pr_debug ("loading %s\n" , path); - -return libbpf_ptr (bpf_object_open (path,NULL ,0 , opts)); +return libbpf_ptr (bpf_object_open (path,NULL ,0 ,NULL , opts)); }struct bpf_object *bpf_object__open (const char *path)
@@ -7992,10 +7989,15 @@ struct bpf_object * bpf_object__open_mem(const void *obj_buf, size_t obj_buf_sz, const struct bpf_object_open_opts *opts) { + char tmp_name[64]; +if (!obj_buf || obj_buf_sz ==0 )return libbpf_err_ptr (-EINVAL ); - return libbpf_ptr(bpf_object_open(NULL, obj_buf, obj_buf_sz, opts)); +/* create a (quite useless) default "name" for this memory buffer object */ +snprintf (tmp_name,sizeof (tmp_name),"%lx-%zx" , (unsigned long )obj_buf, obj_buf_sz); + +return libbpf_ptr (bpf_object_open (NULL , obj_buf, obj_buf_sz, tmp_name, opts)); }static int bpf_object_unload (struct bpf_object *obj)
@@ -13718,29 +13720,13 @@ static int populate_skeleton_progs(const struct bpf_object *obj,int bpf_object__open_skeleton (struct bpf_object_skeleton *s,const struct bpf_object_open_opts *opts) { -DECLARE_LIBBPF_OPTS (bpf_object_open_opts, skel_opts, - .object_name = s->name, - );struct bpf_object *obj;int err; -/* Attempt to preserve opts->object_name, unless overriden by user -* explicitly. Overwriting object name for skeletons is discouraged, -* as it breaks global data maps, because they contain object name -* prefix as their own map name prefix. When skeleton is generated, -* bpftool is making an assumption that this name will stay the same. -*/ -if (opts) { -memcpy (&skel_opts, opts,sizeof (*opts)); -if (!opts->object_name) - skel_opts.object_name = s->name; - } - - obj =bpf_object__open_mem (s->data, s->data_sz, &skel_opts); - err =libbpf_get_error (obj); -if (err) { -pr_warn ("failed to initialize skeleton BPF object '%s': %d\n" , - s->name, err); + obj =bpf_object_open (NULL , s->data, s->data_sz, s->name, opts); +if (IS_ERR (obj)) { + err =PTR_ERR (obj); +pr_warn ("failed to initialize skeleton BPF object '%s': %d\n" , s->name, err);return libbpf_err (err); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 271/634 s390/ap: Fix deadlock caused by recursive lock of the AP bus scan mutex
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harald Freudenberger <[email protected]>
[ Upstream commit 56199bb956c3ea82e39c72d2972ebf8c18c6a8c0 ]
There is a possibility to deadlock with an recursive lock of the AP bus scan mutex ap_scan_bus_mutex:
... kernel: ============================================
... kernel: WARNING: possible recursive locking detected
... kernel: 5.14.0-496.el9.s390x #3 Not tainted
... kernel: --------------------------------------------
... kernel: kworker/12:1/130 is trying to acquire lock:
... kernel: 0000000358bc1510 (ap_scan_bus_mutex){+.+.}-{3:3}, at: ap_bus_force_rescan+0x92/0x108 ... kernel:
but task is already holding lock:
... kernel: 0000000358bc1510 (ap_scan_bus_mutex){+.+.}-{3:3}, at: ap_scan_bus_wq_callback+0x28/0x60 ... kernel:
other info that might help us debug this:
... kernel: Possible unsafe locking scenario:
... kernel: CPU0
... kernel: ----
... kernel: lock(ap_scan_bus_mutex);
... kernel: lock(ap_scan_bus_mutex);
... kernel:
*** DEADLOCK ***
Here is how the callstack looks like:
... [<00000003576fe9ce>] process_one_work+0x2a6/0x748
... [<0000000358150c00>] ap_scan_bus_wq_callback+0x40/0x60 <- mutex locked
... [<00000003581506e2>] ap_scan_bus+0x5a/0x3b0
... [<000000035815037c>] ap_scan_adapter+0x5b4/0x8c0
... [<000000035814fa34>] ap_scan_domains+0x2d4/0x668
... [<0000000357d989b4>] device_add+0x4a4/0x6b8
... [<0000000357d9bb54>] bus_probe_device+0xb4/0xc8
... [<0000000357d9daa8>] __device_attach+0x120/0x1b0
... [<0000000357d9a632>] bus_for_each_drv+0x8a/0xd0
... [<0000000357d9d548>] __device_attach_driver+0xc0/0x140
... [<0000000357d9d3d8>] driver_probe_device+0x40/0xf0
... [<0000000357d9cec2>] really_probe+0xd2/0x460
... [<000000035814d7b0>] ap_device_probe+0x150/0x208
... [<000003ff802a5c46>] zcrypt_cex4_queue_probe+0xb6/0x1c0 [zcrypt_cex4] ... [<000003ff7fb2d36e>] zcrypt_queue_register+0xe6/0x1b0 [zcrypt] ... [<000003ff7fb2c8ac>] zcrypt_rng_device_add+0x94/0xd8 [zcrypt] ... [<0000000357d7bc52>] hwrng_register+0x212/0x228
... [<0000000357d7b8c2>] add_early_randomness+0x102/0x110
... [<000003ff7fb29c94>] zcrypt_rng_data_read+0x94/0xb8 [zcrypt]
... [<0000000358150aca>] ap_bus_force_rescan+0x92/0x108
... [<0000000358177572>] mutex_lock_interruptible_nested+0x32/0x40 <- lock again
Note this only happens when the very first random data providing crypto card appears via hot plug in the system AND is in disabled state ("deconfig"). Then the initial pull of random data fails and a re-scan of the AP bus is triggered while already in the middle of an AP bus scan caused by the appearing new hardware.
The fix is relatively simple once the scenario us understood:
The AP bus force rescan function will immediately return if there is currently an AP bus scan running with the very same thread id.
--- drivers/s390/crypto/ap_bus.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
drivers/s390/crypto/ap_bus.c +17 -0
@@ -107,6 +107,7 @@ debug_info_t *ap_dbf_info;static bool ap_scan_bus (void );static bool ap_scan_bus_result;/* result of last ap_scan_bus() */ static DEFINE_MUTEX (ap_scan_bus_mutex);/* mutex ap_scan_bus() invocations */ +static struct task_struct *ap_scan_bus_task;/* thread holding the scan mutex */ static atomic64_t ap_scan_bus_count;/* counter ap_scan_bus() invocations */ static int ap_scan_bus_time =AP_CONFIG_TIME ;static struct timer_list ap_scan_bus_timer;
@@ -1006,11 +1007,25 @@ bool ap_bus_force_rescan(void)if (scan_counter <=0 ) goto out; +/* +* There is one unlikely but nevertheless valid scenario where the +* thread holding the mutex may try to send some crypto load but +* all cards are offline so a rescan is triggered which causes +* a recursive call of ap_bus_force_rescan(). A simple return if +* the mutex is already locked by this thread solves this. +*/ +if (mutex_is_locked (&ap_scan_bus_mutex)) { +if (ap_scan_bus_task == current) + goto out; + } +/* Try to acquire the AP scan bus mutex */ if (mutex_trylock (&ap_scan_bus_mutex)) {/* mutex acquired, run the AP bus scan */ + ap_scan_bus_task = current; ap_scan_bus_result =ap_scan_bus (); rc = ap_scan_bus_result; + ap_scan_bus_task =NULL ;mutex_unlock (&ap_scan_bus_mutex); goto out; }
@@ -2284,7 +2299,9 @@ static void ap_scan_bus_wq_callback(struct work_struct *unused)* system_long_wq which invokes this function here again. */ if (mutex_trylock (&ap_scan_bus_mutex)) { + ap_scan_bus_task = current; ap_scan_bus_result =ap_scan_bus (); + ap_scan_bus_task =NULL ;mutex_unlock (&ap_scan_bus_mutex); } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 272/634 xz: cleanup CRC32 edits from 2018
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lasse Collin <[email protected]>
[ Upstream commit 2ee96abef214550d9e92f5143ee3ac1fd1323e67 ]
In 2018, a dependency on <linux/crc32poly.h> was added to avoid duplicating the same constant in multiple files. Two months later it was found to be a bad idea and the definition of CRC32_POLY_LE macro was moved into xz_private.h to avoid including <linux/crc32poly.h>.
xz_private.h is a wrong place for it too. Revert back to the upstream version which has the poly in xz_crc32_init() in xz_crc32.c.
--- lib/xz/xz_crc32.c | 2 +- lib/xz/xz_private.h | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-)
lib/xz/xz_crc32.c +1 -1
@@ -29,7 +29,7 @@ STATIC_RW_DATA uint32_t xz_crc32_table[256]; XZ_EXTERN void xz_crc32_init(void) { -const uint32_t poly =CRC32_POLY_LE ; +const uint32_t poly =0xEDB88320 ;uint32_t i;uint32_t j;
lib/xz/xz_private.h +0 -4
@@ -105,10 +105,6 @@# endif #endif -#ifndef CRC32_POLY_LE -#define CRC32_POLY_LE 0xedb88320 -#endif -/* * Allocate memory for LZMA2 decoder. xz_dec_lzma2_reset() must be used * before calling xz_dec_lzma2_run().
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 273/634 kthread: fix task state in kthread worker if being frozen
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Yu <[email protected]>
[ Upstream commit e16c7b07784f3fb03025939c4590b9a7c64970a7 ]
When analyzing a kernel waring message, Peter pointed out that there is a race condition when the kworker is being frozen and falls into try_to_freeze() with TASK_INTERRUPTIBLE, which could trigger a might_sleep() warning in try_to_freeze(). Although the root cause is not related to freeze()[1], it is still worthy to fix this issue ahead.
One possible race scenario:
CPU 0 CPU 1
----- -----
// kthread_worker_fn
set_current_state(TASK_INTERRUPTIBLE);
suspend_freeze_processes()
freeze_processes
static_branch_inc(&freezer_active);
freeze_kernel_threads
pm_nosig_freezing = true;
if (work) { //false
__set_current_state(TASK_RUNNING);
} else if (!freezing(current)) //false, been frozen
freezing():
if (static_branch_unlikely(&freezer_active))
if (pm_nosig_freezing)
return true;
schedule()
}
// state is still TASK_INTERRUPTIBLE
try_to_freeze()
might_sleep() <--- warningFix this by explicitly set the TASK_RUNNING before entering try_to_freeze().
--- kernel/kthread.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
kernel/kthread.c +9 -1
@@ -845,8 +845,16 @@ int kthread_worker_fn(void *worker_ptr)* event only cares about the address. */ trace_sched_kthread_work_execute_end (work, func); - }else if (!freezing (current)) + }else if (!freezing (current)) {schedule (); + }else { +/* +* Handle the case where the current remains +* TASK_INTERRUPTIBLE. try_to_freeze() expects +* the current to be TASK_RUNNING. +*/ +__set_current_state (TASK_RUNNING ); + }try_to_freeze ();cond_resched ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 274/634 ext4: clear EXT4_GROUP_INFO_WAS_TRIMMED_BIT even mount with discard
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: yangerkun <[email protected]>
[ Upstream commit 20cee68f5b44fdc2942d20f3172a262ec247b117 ]
Commit 3d56b8d2c74c ("ext4: Speed up FITRIM by recording flags in ext4_group_info") speed up fstrim by skipping trim trimmed group. We also has the chance to clear trimmed once there exists some block free for this group(mount without discard), and the next trim for this group will work well too.
For mount with discard, we will issue dicard when we free blocks, so leave trimmed flag keep alive to skip useless trim trigger from userspace seems reasonable. But for some case like ext4 build on dm-thinpool(ext4 blocksize 4K, pool blocksize 128K), discard from ext4 maybe unaligned for dm thinpool, and thinpool will just finish this discard(see process_discard_bio when begein equals to end) without actually process discard. For this case, trim from userspace can really help us to free some thinpool block.
So convert to clear trimmed flag for all case no matter mounted with discard or not.
--- fs/ext4/mballoc.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
fs/ext4/mballoc.c +4 -6
@@ -3887,11 +3887,8 @@ static void ext4_free_data_in_buddy(struct super_block *sb,/* * Clear the trimmed flag for the group so that the next * ext4_trim_fs can trim it. -* If the volume is mounted with -o discard, online discard -* is supported and the free blocks will be trimmed online. */ -if (!test_opt (sb,DISCARD )) -EXT4_MB_GRP_CLEAR_TRIMMED (db); +EXT4_MB_GRP_CLEAR_TRIMMED (db);if (!db->bb_free_root.rb_node) {/* No more items in the per group rb tree
@@ -6515,8 +6512,9 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode," group:%u block:%d count:%lu failed" " with %d" , block_group, bit, count, err); - }else -EXT4_MB_GRP_CLEAR_TRIMMED (e4b.bd_info); + } + +EXT4_MB_GRP_CLEAR_TRIMMED (e4b.bd_info);ext4_lock_group (sb, block_group);mb_free_blocks (inode, &e4b, bit, count_clusters);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 275/634 sched/deadline: Fix schedstats vs deadline servers
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huang Shijie <[email protected]>
[ Upstream commit 9c602adb799e72ee537c0c7ca7e828c3fe2acad6 ]
In dl_server_start(), when schedstats is enabled, the following happens:
dl_server_start()
dl_se->dl_server = 1;
enqueue_dl_entity()
update_stats_enqueue_dl()
__schedstats_from_dl_se()
dl_task_of()
BUG_ON(dl_server(dl_se));Since only tasks have schedstats and internal entries do not, avoid trying to update stats in this case.
--- kernel/sched/deadline.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-)
kernel/sched/deadline.c +16 -22
@@ -1599,46 +1599,40 @@ static inline bool __dl_less(struct rb_node *a, const struct rb_node *b)return dl_time_before (__node_2_dle (a)->deadline,__node_2_dle (b)->deadline); } -static inline struct sched_statistics * +static __always_inline struct sched_statistics *__schedstats_from_dl_se (struct sched_dl_entity *dl_se) { +if (!schedstat_enabled ()) +return NULL ; + +if (dl_server (dl_se)) +return NULL ; +return &dl_task_of (dl_se)->stats; }static inline void update_stats_wait_start_dl (struct dl_rq *dl_rq,struct sched_dl_entity *dl_se) { -struct sched_statistics *stats; - -if (!schedstat_enabled ()) -return ; - - stats =__schedstats_from_dl_se (dl_se); -__update_stats_wait_start (rq_of_dl_rq (dl_rq),dl_task_of (dl_se), stats); +struct sched_statistics *stats =__schedstats_from_dl_se (dl_se); +if (stats) +__update_stats_wait_start (rq_of_dl_rq (dl_rq),dl_task_of (dl_se), stats); }static inline void update_stats_wait_end_dl (struct dl_rq *dl_rq,struct sched_dl_entity *dl_se) { -struct sched_statistics *stats; - -if (!schedstat_enabled ()) -return ; - - stats =__schedstats_from_dl_se (dl_se); -__update_stats_wait_end (rq_of_dl_rq (dl_rq),dl_task_of (dl_se), stats); +struct sched_statistics *stats =__schedstats_from_dl_se (dl_se); +if (stats) +__update_stats_wait_end (rq_of_dl_rq (dl_rq),dl_task_of (dl_se), stats); }static inline void update_stats_enqueue_sleeper_dl (struct dl_rq *dl_rq,struct sched_dl_entity *dl_se) { -struct sched_statistics *stats; - -if (!schedstat_enabled ()) -return ; - - stats =__schedstats_from_dl_se (dl_se); -__update_stats_enqueue_sleeper (rq_of_dl_rq (dl_rq),dl_task_of (dl_se), stats); +struct sched_statistics *stats =__schedstats_from_dl_se (dl_se); +if (stats) +__update_stats_enqueue_sleeper (rq_of_dl_rq (dl_rq),dl_task_of (dl_se), stats); } static inline void
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 276/634 smackfs: Use rcu_assign_pointer() to ensure safe assignment in smk_set_cipso
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiawei Ye <[email protected]>
[ Upstream commit 2749749afa071f8a0e405605de9da615e771a7ce ]
In the smk_set_cipso function, the skp->smk_netlabel.attr.mls.cat field is directly assigned to a new value without using the appropriate RCU pointer assignment functions. According to RCU usage rules, this is illegal and can lead to unpredictable behavior, including data inconsistencies and impossible-to-diagnose memory corruption issues.
This possible bug was identified using a static analysis tool developed by myself, specifically designed to detect RCU-related issues.
To address this, the assignment is now done using rcu_assign_pointer(), which ensures that the pointer assignment is done safely, with the necessary memory barriers and synchronization. This change prevents potential RCU dereference issues by ensuring that the cat field is safely updated while still adhering to RCU's requirements.
--- security/smack/smackfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
security/smack/smackfs.c +1 -1
@@ -932,7 +932,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, }if (rc >=0 ) { old_cat = skp->smk_netlabel.attr.mls.cat; - skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat; +rcu_assign_pointer (skp->smk_netlabel.attr.mls.cat, ncats.attr.mls.cat); skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;synchronize_rcu ();netlbl_catmap_free (old_cat);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 277/634 ext4: avoid buffer_head leak in ext4_mark_inode_used()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kemeng Shi <[email protected]>
[ Upstream commit 5e5b2a56c57def1b41efd49596621504d7bcc61c ]
Release inode_bitmap_bh from ext4_read_inode_bitmap() in ext4_mark_inode_used() to avoid buffer_head leak.
By the way, remove unneeded goto for invalid ino when inode_bitmap_bh is NULL.
--- fs/ext4/ialloc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/ext4/ialloc.c +3 -2
@@ -755,10 +755,10 @@ int ext4_mark_inode_used(struct super_block *sb, int ino)struct ext4_group_desc *gdp;ext4_group_t group;int bit; -int err = -EFSCORRUPTED ; +int err;if (ino <EXT4_FIRST_INO (sb) || ino > max_ino) - goto out; +return -EFSCORRUPTED ; group = (ino -1 ) /EXT4_INODES_PER_GROUP (sb); bit = (ino -1 ) %EXT4_INODES_PER_GROUP (sb);
@@ -860,6 +860,7 @@ int ext4_mark_inode_used(struct super_block *sb, int ino) err =ext4_handle_dirty_metadata (NULL ,NULL , group_desc_bh);sync_dirty_buffer (group_desc_bh); out: +brelse (inode_bitmap_bh);return err; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 278/634 ext4: avoid potential buffer_head leak in __ext4_new_inode()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kemeng Shi <[email protected]>
[ Upstream commit 227d31b9214d1b9513383cf6c7180628d4b3b61f ]
If a group is marked EXT4_GROUP_INFO_IBITMAP_CORRUPT after it's inode bitmap buffer_head was successfully verified, then __ext4_new_inode() will get a valid inode_bitmap_bh of a corrupted group from ext4_read_inode_bitmap() in which case inode_bitmap_bh misses a release. Hnadle "IS_ERR(inode_bitmap_bh)" and group corruption separately like how ext4_free_inode() does to avoid buffer_head leak.
--- fs/ext4/ialloc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/ext4/ialloc.c +4 -3
@@ -1054,12 +1054,13 @@ struct inode *__ext4_new_inode(struct mnt_idmap *idmap,brelse (inode_bitmap_bh); inode_bitmap_bh =ext4_read_inode_bitmap (sb, group);/* Skip groups with suspicious inode tables */ -if (((!(sbi->s_mount_state &EXT4_FC_REPLAY )) - &&EXT4_MB_GRP_IBITMAP_CORRUPT (grp)) || -IS_ERR (inode_bitmap_bh)) { +if (IS_ERR (inode_bitmap_bh)) { inode_bitmap_bh =NULL ; goto next_group; } +if (!(sbi->s_mount_state &EXT4_FC_REPLAY ) && +EXT4_MB_GRP_IBITMAP_CORRUPT (grp)) + goto next_group; repeat_in_this_group: ret2 =find_inode_bit (sb, group, inode_bitmap_bh, &ino);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 279/634 ext4: avoid negative min_clusters in find_group_orlov()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kemeng Shi <[email protected]>
[ Upstream commit bb0a12c3439b10d88412fd3102df5b9a6e3cd6dc ]
min_clusters is signed integer and will be converted to unsigned integer when compared with unsigned number stats.free_clusters. If min_clusters is negative, it will be converted to a huge unsigned value in which case all groups may not meet the actual desired free clusters.
Set negative min_clusters to 0 to avoid unexpected behavior.
--- fs/ext4/ialloc.c | 2 ++ 1 file changed, 2 insertions(+)
fs/ext4/ialloc.c +2 -0
@@ -514,6 +514,8 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,if (min_inodes <1 ) min_inodes =1 ; min_clusters = avefreec -EXT4_CLUSTERS_PER_GROUP (sb)*flex_size /4 ; +if (min_clusters <0 ) + min_clusters =0 ;/* * Start looking in the flex group where we last allocated an
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 280/634 ext4: return error on ext4_find_inline_entry
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thadeu Lima de Souza Cascardo <[email protected]>
[ Upstream commit 4d231b91a944f3cab355fce65af5871fb5d7735b ]
In case of errors when reading an inode from disk or traversing inline directory entries, return an error-encoded ERR_PTR instead of returning NULL. ext4_find_inline_entry only caller, __ext4_find_entry already returns such encoded errors.
Stable-dep-of: c6b72f5d82b1 ("ext4: avoid OOB when system.data xattr changes underneath the filesystem")
--- fs/ext4/inline.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
fs/ext4/inline.c +7 -3
@@ -1669,8 +1669,9 @@ struct buffer_head *ext4_find_inline_entry(struct inode *dir,void *inline_start;int inline_size; -if (ext4_get_inode_loc (dir, &iloc)) -return NULL ; + ret =ext4_get_inode_loc (dir, &iloc); +if (ret) +return ERR_PTR (ret);down_read (&EXT4_I (dir)->xattr_sem);if (!ext4_has_inline_data (dir)) {
@@ -1701,7 +1702,10 @@ struct buffer_head *ext4_find_inline_entry(struct inode *dir, out:brelse (iloc.bh); - iloc.bh =NULL ; +if (ret <0 ) + iloc.bh =ERR_PTR (ret); +else + iloc.bh =NULL ; out_find:up_read (&EXT4_I (dir)->xattr_sem);return iloc.bh;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 281/634 ext4: avoid OOB when system.data xattr changes underneath the filesystem
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thadeu Lima de Souza Cascardo <[email protected]>
[ Upstream commit c6b72f5d82b1017bad80f9ebf502832fc321d796 ]
When looking up for an entry in an inlined directory, if e_value_offs is changed underneath the filesystem by some change in the block device, it will lead to an out-of-bounds access that KASAN detects as an UAF.
EXT4-fs (loop0): mounted filesystem 00000000-0000-0000-0000-000000000000 r/w without journal. Quota mode: none.
loop0: detected capacity change from 2048 to 2047
==================================================================
BUG: KASAN: use-after-free in ext4_search_dir+0xf2/0x1c0 fs/ext4/namei.c:1500 Read of size 1 at addr ffff88803e91130f by task syz-executor269/5103 CPU: 0 UID: 0 PID: 5103 Comm: syz-executor269 Not tainted 6.11.0-rc4-syzkaller #0 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 Call Trace: <TASK> __dump_stack lib/dump_stack.c:93 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:119 print_address_description mm/kasan/report.c:377 [inline] print_report+0x169/0x550 mm/kasan/report.c:488 kasan_report+0x143/0x180 mm/kasan/report.c:601 ext4_search_dir+0xf2/0x1c0 fs/ext4/namei.c:1500 ext4_find_inline_entry+0x4be/0x5e0 fs/ext4/inline.c:1697 __ext4_find_entry+0x2b4/0x1b30 fs/ext4/namei.c:1573 ext4_lookup_entry fs/ext4/namei.c:1727 [inline] ext4_lookup+0x15f/0x750 fs/ext4/namei.c:1795 lookup_one_qstr_excl+0x11f/0x260 fs/namei.c:1633 filename_create+0x297/0x540 fs/namei.c:3980 do_symlinkat+0xf9/0x3a0 fs/namei.c:4587 __do_sys_symlinkat fs/namei.c:4610 [inline] __se_sys_symlinkat fs/namei.c:4607 [inline] __x64_sys_symlinkat+0x95/0xb0 fs/namei.c:4607 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f3e73ced469 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 21 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fff4d40c258 EFLAGS: 00000246 ORIG_RAX: 000000000000010a RAX: ffffffffffffffda RBX: 0032656c69662f2e RCX: 00007f3e73ced469 RDX: 0000000020000200 RSI: 00000000ffffff9c RDI: 00000000200001c0 RBP: 0000000000000000 R08: 00007fff4d40c290 R09: 00007fff4d40c290 R10: 0023706f6f6c2f76 R11: 0000000000000246 R12: 00007fff4d40c27c R13: 0000000000000003 R14: 431bde82d7b634db R15: 00007fff4d40c2b0 </TASK>
Calling ext4_xattr_ibody_find right after reading the inode with ext4_get_inode_loc will lead to a check of the validity of the xattrs, avoiding this problem.
--- fs/ext4/inline.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-)
fs/ext4/inline.c +21 -10
@@ -1664,25 +1664,36 @@ struct buffer_head *ext4_find_inline_entry(struct inode *dir,struct ext4_dir_entry_2 **res_dir, int *has_inline_data) { + struct ext4_xattr_ibody_find is = { + .s = { .not_found = -ENODATA , }, + }; +struct ext4_xattr_info i = { + .name_index =EXT4_XATTR_INDEX_SYSTEM , + .name =EXT4_XATTR_SYSTEM_DATA , + };int ret; -struct ext4_iloc iloc;void *inline_start;int inline_size; - ret =ext4_get_inode_loc (dir, &iloc); + ret =ext4_get_inode_loc (dir, &is.iloc);if (ret)return ERR_PTR (ret);down_read (&EXT4_I (dir)->xattr_sem); + + ret =ext4_xattr_ibody_find (dir, &i, &is); +if (ret) + goto out; +if (!ext4_has_inline_data (dir)) { *has_inline_data =0 ; goto out; } - inline_start = (void *)ext4_raw_inode (&iloc)->i_block + + inline_start = (void *)ext4_raw_inode (&is.iloc)->i_block +EXT4_INLINE_DOTDOT_SIZE ; inline_size =EXT4_MIN_INLINE_DATA_SIZE -EXT4_INLINE_DOTDOT_SIZE ; - ret =ext4_search_dir (iloc.bh, inline_start, inline_size, + ret =ext4_search_dir (is.iloc.bh, inline_start, inline_size, dir, fname,0 , res_dir);if (ret ==1 ) goto out_find;
@@ -1692,23 +1703,23 @@ struct buffer_head *ext4_find_inline_entry(struct inode *dir,if (ext4_get_inline_size (dir) ==EXT4_MIN_INLINE_DATA_SIZE ) goto out; - inline_start =ext4_get_inline_xattr_pos (dir, &iloc); + inline_start =ext4_get_inline_xattr_pos (dir, &is.iloc); inline_size =ext4_get_inline_size (dir) -EXT4_MIN_INLINE_DATA_SIZE ; - ret =ext4_search_dir (iloc.bh, inline_start, inline_size, + ret =ext4_search_dir (is.iloc.bh, inline_start, inline_size, dir, fname,0 , res_dir);if (ret ==1 ) goto out_find; out: -brelse (iloc.bh); +brelse (is.iloc.bh);if (ret <0 ) - iloc.bh =ERR_PTR (ret); + is.iloc.bh =ERR_PTR (ret);else - iloc.bh =NULL ; + is.iloc.bh =NULL ; out_find:up_read (&EXT4_I (dir)->xattr_sem); -return iloc.bh; +return is.iloc.bh; } int ext4_delete_inline_entry(handle_t *handle,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 282/634 ext4: check stripe size compatibility on remount as well
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ojaswin Mujoo <[email protected]>
[ Upstream commit ee85e0938aa8f9846d21e4d302c3cf6a2a75110d ]
We disable stripe size in __ext4_fill_super if it is not a multiple of the cluster ratio however this check is missed when trying to remount. This can leave us with cases where stripe < cluster_ratio after remount:set making EXT4_B2C(sbi->s_stripe) become 0 that can cause some unforeseen bugs like divide by 0.
Fix that by adding the check in remount path as well.
--- fs/ext4/super.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-)
fs/ext4/super.c +22 -7
@@ -5177,6 +5177,18 @@ static int ext4_block_group_meta_init(struct super_block *sb, int silent)return 0 ; } +/* +* It's hard to get stripe aligned blocks if stripe is not aligned with +* cluster, just disable stripe and alert user to simplify code and avoid +* stripe aligned allocation which will rarely succeed. +*/ +static bool ext4_is_stripe_incompatible (struct super_block *sb,unsigned long stripe) +{ +struct ext4_sb_info *sbi =EXT4_SB (sb); +return (stripe >0 && sbi->s_cluster_ratio >1 && + stripe % sbi->s_cluster_ratio !=0 ); +} +static int __ext4_fill_super (struct fs_context *fc,struct super_block *sb) {struct ext4_super_block *es =NULL ;
@@ -5284,13 +5296,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb) goto failed_mount3; sbi->s_stripe =ext4_get_stripe_size (sbi); -/* -* It's hard to get stripe aligned blocks if stripe is not aligned with -* cluster, just disable stripe and alert user to simpfy code and avoid -* stripe aligned allocation which will rarely successes. -*/ -if (sbi->s_stripe >0 && sbi->s_cluster_ratio >1 && - sbi->s_stripe % sbi->s_cluster_ratio !=0 ) { +if (ext4_is_stripe_incompatible (sb, sbi->s_stripe)) { ext4_msg(sb, KERN_WARNING, "stripe (%lu) is not aligned with cluster size (%u), " "stripe is disabled",
@@ -6453,6 +6459,15 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb) } +if ((ctx->spec & EXT4_SPEC_s_stripe) && +ext4_is_stripe_incompatible (sb, ctx->s_stripe)) { +ext4_msg (sb,KERN_WARNING , +"stripe (%lu) is not aligned with cluster size (%u), " +"stripe is disabled" , + ctx->s_stripe, sbi->s_cluster_ratio); + ctx->s_stripe =0 ; + } +/* * Changing the DIOREAD_NOLOCK or DELALLOC mount options may cause * two calls to ext4_should_dioread_nolock() to return inconsistent
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 283/634 sched/numa: Fix the vma scan starving issue
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yujie Liu <[email protected]>
[ Upstream commit f22cde4371f3c624e947a35b075c06c771442a43 ]
Problem statement:
Since commit fc137c0ddab2 ("sched/numa: enhance vma scanning logic"), the Numa vma scan overhead has been reduced a lot. Meanwhile, the reducing of the vma scan might create less Numa page fault information. The insufficient information makes it harder for the Numa balancer to make decision. Later, commit b7a5b537c55c08 ("sched/numa: Complete scanning of partial VMAs regardless of PID activity") and commit 84db47ca7146d7 ("sched/numa: Fix mm numa_scan_seq based unconditional scan") are found to bring back part of the performance.
Recently when running SPECcpu omnetpp_r on a 320 CPUs/2 Sockets system, a long duration of remote Numa node read was observed by PMU events: A few cores having ~500MB/s remote memory access for ~20 seconds. It causes high core-to-core variance and performance penalty. After the investigation, it is found that many vmas are skipped due to the active PID check. According to the trace events, in most cases, vma_is_accessed() returns false because the history access info stored in pids_active array has been cleared.
Proposal:
The main idea is to adjust vma_is_accessed() to let it return true easier. Thus compare the diff between mm->numa_scan_seq and vma->numab_state->prev_scan_seq. If the diff has exceeded the threshold, scan the vma.
This patch especially helps the cases where there are small number of threads, like the process-based SPECcpu. Without this patch, if the SPECcpu process access the vma at the beginning, then sleeps for a long time, the pid_active array will be cleared. A a result, if this process is woken up again, it never has a chance to set prot_none anymore. Because only the first 2 times of access is granted for vma scan:
(current->mm->numa_scan_seq) - vma->numab_state->start_scan_seq) < 2 to be worse, no other threads within the task can help set the prot_none. This causes information lost.
Raghavendra helped test current patch and got the positive result on the AMD platform:
autonumabench NUMA01
base patched Amean syst-NUMA01 194.05 ( 0.00%) 165.11 * 14.92%* Amean elsp-NUMA01 324.86 ( 0.00%) 315.58 * 2.86%*
Duration User 380345.36 368252.04
Duration System 1358.89 1156.23 Duration Elapsed 2277.45 2213.25
autonumabench NUMA02
Amean syst-NUMA02 1.12 ( 0.00%) 1.09 * 2.93%* Amean elsp-NUMA02 3.50 ( 0.00%) 3.56 * -1.84%*
Duration User 1513.23 1575.48
Duration System 8.33 8.13
Duration Elapsed 28.59 29.71
kernbench
Amean user-256 22935.42 ( 0.00%) 22535.19 * 1.75%* Amean syst-256 7284.16 ( 0.00%) 7608.72 * -4.46%* Amean elsp-256 159.01 ( 0.00%) 158.17 * 0.53%*
Duration User 68816.41 67615.74 Duration System 21873.94 22848.08
Duration Elapsed 506.66 504.55
Intel 256 CPUs/2 Sockets:
autonuma benchmark also shows improvements:
v6.10-rc5 v6.10-rc5
+patch
Amean syst-NUMA01 245.85 ( 0.00%) 230.84 * 6.11%*
Amean syst-NUMA01_THREADLOCAL 205.27 ( 0.00%) 191.86 * 6.53%*
Amean syst-NUMA02 18.57 ( 0.00%) 18.09 * 2.58%*
Amean syst-NUMA02_SMT 2.63 ( 0.00%) 2.54 * 3.47%*
Amean elsp-NUMA01 517.17 ( 0.00%) 526.34 * -1.77%*
Amean elsp-NUMA01_THREADLOCAL 99.92 ( 0.00%) 100.59 * -0.67%*
Amean elsp-NUMA02 15.81 ( 0.00%) 15.72 * 0.59%*
Amean elsp-NUMA02_SMT 13.23 ( 0.00%) 12.89 * 2.53%* v6.10-rc5 v6.10-rc5
+patch
Duration User 1064010.16 1075416.23
Duration System 3307.64 3104.66
Duration Elapsed 4537.54 4604.73The SPECcpu remote node access issue disappears with the patch applied.
--- kernel/sched/fair.c | 9 +++++++++ 1 file changed, 9 insertions(+)
kernel/sched/fair.c +9 -0
@@ -3188,6 +3188,15 @@ static bool vma_is_accessed(struct mm_struct *mm, struct vm_area_struct *vma)return true; } +/* +* This vma has not been accessed for a while, and if the number +* the threads in the same process is low, which means no other +* threads can help scan this vma, force a vma scan. +*/ +if (READ_ONCE (mm->numa_scan_seq) > + (vma->numab_state->prev_scan_seq +get_nr_threads (current))) +return true; +return false; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 284/634 nilfs2: fix potential null-ptr-deref in nilfs_btree_insert()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryusuke Konishi <[email protected]>
[ Upstream commit 9403001ad65ae4f4c5de368bdda3a0636b51d51a ]
Patch series "nilfs2: fix potential issues with empty b-tree nodes".
This series addresses three potential issues with empty b-tree nodes that can occur with corrupted filesystem images, including one recently discovered by syzbot.
This patch (of 3):
If a b-tree is broken on the device, and the b-tree height is greater than 2 (the level of the root node is greater than 1) even if the number of child nodes of the b-tree root is 0, a NULL pointer dereference occurs in nilfs_btree_prepare_insert(), which is called from nilfs_btree_insert().
This is because, when the number of child nodes of the b-tree root is 0, nilfs_btree_do_lookup() does not set the block buffer head in any of path[x].bp_bh, leaving it as the initial value of NULL, but if the level of the b-tree root node is greater than 1, nilfs_btree_get_nonroot_node(), which accesses the buffer memory of path[x].bp_bh, is called.
Fix this issue by adding a check to nilfs_btree_root_broken(), which performs sanity checks when reading the root node from the device, to detect this inconsistency.
Thanks to Lizhi Xu for trying to solve the bug and clarifying the cause early on.
--- fs/nilfs2/btree.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/nilfs2/btree.c +2 -1
@@ -381,7 +381,8 @@ static int nilfs_btree_root_broken(const struct nilfs_btree_node *node,if (unlikely (level <NILFS_BTREE_LEVEL_NODE_MIN || level >=NILFS_BTREE_LEVEL_MAX || nchildren <0 || - nchildren >NILFS_BTREE_ROOT_NCHILDREN_MAX )) { + nchildren >NILFS_BTREE_ROOT_NCHILDREN_MAX || + (nchildren ==0 && level >NILFS_BTREE_LEVEL_NODE_MIN ))) {nilfs_crit (inode->i_sb,"bad btree root (ino=%lu): level = %d, flags = 0x%x, nchildren = %d" , inode->i_ino, level, flags, nchildren);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 285/634 nilfs2: determine empty node blocks as corrupted
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryusuke Konishi <[email protected]>
[ Upstream commit 111b812d3662f3a1b831d19208f83aa711583fe6 ]
Due to the nature of b-trees, nilfs2 itself and admin tools such as mkfs.nilfs2 will never create an intermediate b-tree node block with 0 child nodes, nor will they delete (key, pointer)-entries that would result in such a state. However, it is possible that a b-tree node block is corrupted on the backing device and is read with 0 child nodes.
Because operation is not guaranteed if the number of child nodes is 0 for intermediate node blocks other than the root node, modify nilfs_btree_node_broken(), which performs sanity checks when reading a b-tree node block, so that such cases will be judged as metadata corruption.
--- fs/nilfs2/btree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nilfs2/btree.c +1 -1
@@ -350,7 +350,7 @@ static int nilfs_btree_node_broken(const struct nilfs_btree_node *node,if (unlikely (level <NILFS_BTREE_LEVEL_NODE_MIN || level >=NILFS_BTREE_LEVEL_MAX || (flags &NILFS_BTREE_NODE_ROOT ) || - nchildren <0 || + nchildren <=0 || nchildren >NILFS_BTREE_NODE_NCHILDREN_MAX (size))) { nilfs_crit(inode->i_sb, "bad btree node (ino=%lu, blocknr=%llu): level = %d, flags = 0x%x, nchildren = %d",
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 286/634 nilfs2: fix potential oob read in nilfs_btree_check_delete()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryusuke Konishi <[email protected]>
[ Upstream commit f9c96351aa6718b42a9f42eaf7adce0356bdb5e8 ]
The function nilfs_btree_check_delete(), which checks whether degeneration to direct mapping occurs before deleting a b-tree entry, causes memory access outside the block buffer when retrieving the maximum key if the root node has no entries.
This does not usually happen because b-tree mappings with 0 child nodes are never created by mkfs.nilfs2 or nilfs2 itself. However, it can happen if the b-tree root node read from a device is configured that way, so fix this potential issue by adding a check for that case.
--- fs/nilfs2/btree.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/nilfs2/btree.c +5 -2
@@ -1659,13 +1659,16 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *btree, __u64 key)int nchildren, ret; root =nilfs_btree_get_root (btree); + nchildren =nilfs_btree_node_get_nchildren (root); +if (unlikely (nchildren ==0 )) +return 0 ; +switch (nilfs_btree_height (btree)) {case 2 : bh =NULL ; node = root;break ;case 3 : - nchildren =nilfs_btree_node_get_nchildren (root);if (nchildren >1 )return 0 ; ptr = nilfs_btree_node_get_ptr(root, nchildren - 1,
@@ -1674,12 +1677,12 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *btree, __u64 key)if (ret <0 )return ret; node = (struct nilfs_btree_node *)bh->b_data; + nchildren =nilfs_btree_node_get_nchildren (node);break ;default :return 0 ; } - nchildren =nilfs_btree_node_get_nchildren (node); maxkey =nilfs_btree_node_get_key (node, nchildren -1 ); nextmaxkey = (nchildren >1 ) ?nilfs_btree_node_get_key (node, nchildren -2 ) :0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 287/634 sched/pelt: Use rq_clock_task() for hw_pressure
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Yu <[email protected]>
[ Upstream commit 84d265281d6cea65353fc24146280e0d86ac50cb ]
commit 97450eb90965 ("sched/pelt: Remove shift of thermal clock") removed the decay_shift for hw_pressure. This commit uses the sched_clock_task() in sched_tick() while it replaces the sched_clock_task() with rq_clock_pelt() in __update_blocked_others(). This could bring inconsistence. One possible scenario I can think of is in ___update_load_sum():
u64 delta = now - sa->last_update_time
'now' could be calculated by rq_clock_pelt() from __update_blocked_others(), and last_update_time was calculated by rq_clock_task() previously from sched_tick(). Usually the former chases after the latter, it cause a very large 'delta' and brings unexpected behavior.
--- kernel/sched/fair.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/sched/fair.c +2 -1
@@ -9365,9 +9365,10 @@ static bool __update_blocked_others(struct rq *rq, bool *done) hw_pressure =arch_scale_hw_pressure (cpu_of (rq)); +/* hw_pressure doesn't care about invariance */ decayed =update_rt_rq_load_avg (now, rq, curr_class == &rt_sched_class) |update_dl_rq_load_avg (now, rq, curr_class == &dl_sched_class) | -update_hw_load_avg (now, rq, hw_pressure) | +update_hw_load_avg (rq_clock_task (rq), rq, hw_pressure) |update_irq_load_avg (rq,0 );if (others_have_blocked (rq))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 288/634 bpf: Fix bpf_strtol and bpf_strtoul helpers for 32bit
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <[email protected]>
[ Upstream commit cfe69c50b05510b24e26ccb427c7cc70beafd6c1 ]
The bpf_strtol() and bpf_strtoul() helpers are currently broken on 32bit:
The argument type ARG_PTR_TO_LONG is BPF-side "long", not kernel-side "long" and therefore always considered fixed 64bit no matter if 64 or 32bit underlying architecture.
This contract breaks in case of the two mentioned helpers since their BPF_CALL definition for the helpers was added with {unsigned,}long *res. Meaning, the transition from BPF-side "long" (BPF program) to kernel-side "long" (BPF helper) breaks here.
Both helpers call __bpf_strtoll() with "long long" correctly, but later assigning the result into 32-bit "*(long *)" on 32bit architectures. From a BPF program point of view, this means upper bits will be seen as uninitialised.
Therefore, fix both BPF_CALL signatures to {s,u}64 types to fix this situation.
Now, changing also uapi/bpf.h helper documentation which generates bpf_helper_defs.h for BPF programs is tricky: Changing signatures there to __{s,u}64 would trigger compiler warnings (incompatible pointer types passing 'long *' to parameter of type '__s64 *' (aka 'long long *')) for existing BPF programs.
Leaving the signatures as-is would be fine as from BPF program point of view it is still BPF-side "long" and thus equivalent to __{s,u}64 on 64 or 32bit underlying architectures.
Note that bpf_strtol() and bpf_strtoul() are the only helpers with this issue.
--- kernel/bpf/helpers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/bpf/helpers.c +2 -2
@@ -517,7 +517,7 @@ static int __bpf_strtoll(const char *buf, size_t buf_len, u64 flags, } BPF_CALL_4(bpf_strtol, const char *, buf, size_t, buf_len, u64, flags, - long *, res) + s64 *, res) {long long _res;int err;
@@ -542,7 +542,7 @@ const struct bpf_func_proto bpf_strtol_proto = { }; BPF_CALL_4(bpf_strtoul, const char *, buf, size_t, buf_len, u64, flags, - unsigned long *, res) + u64 *, res) {unsigned long long _res;bool is_negative;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 289/634 bpf: Fix helper writes to read-only maps
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <[email protected]>
[ Upstream commit 32556ce93bc45c730829083cb60f95a2728ea48b ]
Lonial found an issue that despite user- and BPF-side frozen BPF map (like in case of .rodata), it was still possible to write into it from a BPF program side through specific helpers having ARG_PTR_TO_{LONG,INT} as arguments.
In check_func_arg() when the argument is as mentioned, the meta->raw_mode is never set. Later, check_helper_mem_access(), under the case of PTR_TO_MAP_VALUE as register base type, it assumes BPF_READ for the subsequent call to check_map_access_type() and given the BPF map is read-only it succeeds.
The helpers really need to be annotated as ARG_PTR_TO_{LONG,INT} | MEM_UNINIT when results are written into them as opposed to read out of them. The latter indicates that it's okay to pass a pointer to uninitialized memory as the memory is written to anyway.
However, ARG_PTR_TO_{LONG,INT} is a special case of ARG_PTR_TO_FIXED_SIZE_MEM just with additional alignment requirement. So it is better to just get rid of the ARG_PTR_TO_{LONG,INT} special cases altogether and reuse the fixed size memory types. For this, add MEM_ALIGNED to additionally ensure alignment given these helpers write directly into the args via *<ptr> = val. The .arg*_size has been initialized reflecting the actual sizeof(*<ptr>).
MEM_ALIGNED can only be used in combination with MEM_FIXED_SIZE annotated argument types, since in !MEM_FIXED_SIZE cases the verifier does not know the buffer size a priori and therefore cannot blindly write *<ptr> = val.
--- include/linux/bpf.h | 7 +++++-- kernel/bpf/helpers.c | 6 ++++-- kernel/bpf/syscall.c | 3 ++- kernel/bpf/verifier.c | 41 +++++----------------------------------- kernel/trace/bpf_trace.c | 6 ++++-- net/core/filter.c | 6 ++++-- 6 files changed, 24 insertions(+), 45 deletions(-)
include/linux/bpf.h +5 -2
@@ -694,6 +694,11 @@ enum bpf_type_flag {/* DYNPTR points to xdp_buff */ DYNPTR_TYPE_XDP =BIT (16 +BPF_BASE_TYPE_BITS ), +/* Memory must be aligned on some architectures, used in combination with +* MEM_FIXED_SIZE. +*/ +MEM_ALIGNED =BIT (17 +BPF_BASE_TYPE_BITS ), + __BPF_TYPE_FLAG_MAX, __BPF_TYPE_LAST_FLAG = __BPF_TYPE_FLAG_MAX - 1, };
@@ -731,8 +736,6 @@ enum bpf_arg_type {ARG_ANYTHING ,/* any (initialized) argument is ok */ ARG_PTR_TO_SPIN_LOCK ,/* pointer to bpf_spin_lock */ ARG_PTR_TO_SOCK_COMMON ,/* pointer to sock_common */ -ARG_PTR_TO_INT ,/* pointer to int */ -ARG_PTR_TO_LONG ,/* pointer to long */ ARG_PTR_TO_SOCKET ,/* pointer to bpf_sock (fullsock) */ ARG_PTR_TO_BTF_ID ,/* pointer to in-kernel struct */ ARG_PTR_TO_RINGBUF_MEM, /* pointer to dynamically reserved ringbuf memory */
kernel/bpf/helpers.c +4 -2
@@ -538,7 +538,8 @@ const struct bpf_func_proto bpf_strtol_proto = { .arg1_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg2_type = ARG_CONST_SIZE, .arg3_type = ARG_ANYTHING, - .arg4_type = ARG_PTR_TO_LONG, + .arg4_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED, + .arg4_size = sizeof(s64), }; BPF_CALL_4(bpf_strtoul, const char *, buf, size_t, buf_len, u64, flags,
@@ -566,7 +567,8 @@ const struct bpf_func_proto bpf_strtoul_proto = { .arg1_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg2_type = ARG_CONST_SIZE, .arg3_type = ARG_ANYTHING, - .arg4_type = ARG_PTR_TO_LONG, + .arg4_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED, + .arg4_size = sizeof(u64), }; BPF_CALL_3(bpf_strncmp, const char *, s1, u32, s1_sz, const char *, s2)
kernel/bpf/syscall.c +2 -1
@@ -5930,7 +5930,8 @@ static const struct bpf_func_proto bpf_kallsyms_lookup_name_proto = { .arg1_type = ARG_PTR_TO_MEM, .arg2_type = ARG_CONST_SIZE_OR_ZERO, .arg3_type = ARG_ANYTHING, - .arg4_type = ARG_PTR_TO_LONG, + .arg4_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED, + .arg4_size = sizeof(u64), }; static const struct bpf_func_proto *
kernel/bpf/verifier.c +5 -36
71 lines not on this page · raw message
kernel/trace/bpf_trace.c +4 -2
@@ -1226,7 +1226,8 @@ static const struct bpf_func_proto bpf_get_func_arg_proto = { .ret_type = RET_INTEGER, .arg1_type = ARG_PTR_TO_CTX, .arg2_type = ARG_ANYTHING, - .arg3_type = ARG_PTR_TO_LONG, + .arg3_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED, + .arg3_size = sizeof(u64), }; BPF_CALL_2(get_func_ret, void *, ctx, u64 *, value)
@@ -1242,7 +1243,8 @@ static const struct bpf_func_proto bpf_get_func_ret_proto = { .func = get_func_ret, .ret_type = RET_INTEGER, .arg1_type = ARG_PTR_TO_CTX, - .arg2_type = ARG_PTR_TO_LONG, + .arg2_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED, + .arg2_size = sizeof(u64), }; BPF_CALL_1(get_func_arg_cnt, void *, ctx)
net/core/filter.c +4 -2
@@ -6342,7 +6342,8 @@ static const struct bpf_func_proto bpf_skb_check_mtu_proto = { .ret_type = RET_INTEGER, .arg1_type = ARG_PTR_TO_CTX, .arg2_type = ARG_ANYTHING, - .arg3_type = ARG_PTR_TO_INT, + .arg3_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED, + .arg3_size = sizeof(u32), .arg4_type = ARG_ANYTHING, .arg5_type = ARG_ANYTHING, };
@@ -6353,7 +6354,8 @@ static const struct bpf_func_proto bpf_xdp_check_mtu_proto = { .ret_type = RET_INTEGER, .arg1_type = ARG_PTR_TO_CTX, .arg2_type = ARG_ANYTHING, - .arg3_type = ARG_PTR_TO_INT, + .arg3_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED, + .arg3_size = sizeof(u32), .arg4_type = ARG_ANYTHING, .arg5_type = ARG_ANYTHING, };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 290/634 bpf: Improve check_raw_mode_ok test for MEM_UNINIT-tagged types
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <[email protected]>
[ Upstream commit 18752d73c1898fd001569195ba4b0b8c43255f4a ]
When checking malformed helper function signatures, also take other argument types into account aside from just ARG_PTR_TO_UNINIT_MEM.
This concerns (formerly) ARG_PTR_TO_{INT,LONG} given uninitialized memory can be passed there, too.
The func proto sanity check goes back to commit 435faee1aae9 ("bpf, verifier:
add ARG_PTR_TO_RAW_STACK type"), and its purpose was to detect wrong func protos which had more than just one MEM_UNINIT-tagged type as arguments.
The reason more than one is currently not supported is as we mark stack slots with STACK_MISC in check_helper_call() in case of raw mode based on meta.access_size to allow uninitialized stack memory to be passed to helpers when they just write into the buffer.
Probing for base type as well as MEM_UNINIT tagging ensures that other types do not get missed (as it used to be the case for ARG_PTR_TO_{INT,LONG}).
--- kernel/bpf/verifier.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
kernel/bpf/verifier.c +11 -5
@@ -8158,6 +8158,12 @@ static bool arg_type_is_mem_size(enum bpf_arg_type type) type ==ARG_CONST_SIZE_OR_ZERO ; } +static bool arg_type_is_raw_mem (enum bpf_arg_type type) +{ +return base_type (type) ==ARG_PTR_TO_MEM && + type &MEM_UNINIT ; +} +static bool arg_type_is_release (enum bpf_arg_type type) {return type &OBJ_RELEASE ;
@@ -9200,15 +9206,15 @@ static bool check_raw_mode_ok(const struct bpf_func_proto *fn) {int count =0 ; -if (fn->arg1_type ==ARG_PTR_TO_UNINIT_MEM ) +if (arg_type_is_raw_mem (fn->arg1_type)) count++; -if (fn->arg2_type ==ARG_PTR_TO_UNINIT_MEM ) +if (arg_type_is_raw_mem (fn->arg2_type)) count++; -if (fn->arg3_type ==ARG_PTR_TO_UNINIT_MEM ) +if (arg_type_is_raw_mem (fn->arg3_type)) count++; -if (fn->arg4_type ==ARG_PTR_TO_UNINIT_MEM ) +if (arg_type_is_raw_mem (fn->arg4_type)) count++; -if (fn->arg5_type ==ARG_PTR_TO_UNINIT_MEM ) +if (arg_type_is_raw_mem (fn->arg5_type)) count++;/* We only support one arg being in raw mode at the moment,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 291/634 bpf: Zero former ARG_PTR_TO_{LONG,INT} args in case of error
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <[email protected]>
[ Upstream commit 4b3786a6c5397dc220b1483d8e2f4867743e966f ]
For all non-tracing helpers which formerly had ARG_PTR_TO_{LONG,INT} as input arguments, zero the value for the case of an error as otherwise it could leak memory. For tracing, it is not needed given CAP_PERFMON can already read all kernel memory anyway hence bpf_get_func_arg() and bpf_get_func_ret() is skipped in here.
Also, the MTU helpers mtu_len pointer value is being written but also read. Technically, the MEM_UNINIT should not be there in order to always force init. Removing MEM_UNINIT needs more verifier rework though: MEM_UNINIT right now implies two things actually: i) write into memory, ii) memory does not have to be initialized. If we lift MEM_UNINIT, it then becomes: i) read into memory, ii) memory must be initialized. This means that for bpf_*_check_mtu() we're readding the issue we're trying to fix, that is, it would then be able to write back into things like .rodata BPF maps. Follow-up work will rework the MEM_UNINIT semantics such that the intent can be better expressed. For now just clear the *mtu_len on error path which can be lifted later again.
--- kernel/bpf/helpers.c | 2 ++ kernel/bpf/syscall.c | 1 + net/core/filter.c | 44 +++++++++++++++++++++++--------------------- 3 files changed, 26 insertions(+), 21 deletions(-)
kernel/bpf/helpers.c +2 -0
@@ -522,6 +522,7 @@ BPF_CALL_4(bpf_strtol, const char *, buf, size_t, buf_len, u64, flags,long long _res;int err; + *res =0 ; err =__bpf_strtoll (buf, buf_len, flags, &_res);if (err <0 )return err;
@@ -549,6 +550,7 @@ BPF_CALL_4(bpf_strtoul, const char *, buf, size_t, buf_len, u64, flags,bool is_negative;int err; + *res =0 ; err =__bpf_strtoull (buf, buf_len, flags, &_res, &is_negative);if (err <0 )return err;
kernel/bpf/syscall.c +1 -0
@@ -5910,6 +5910,7 @@ static const struct bpf_func_proto bpf_sys_close_proto = { BPF_CALL_4(bpf_kallsyms_lookup_name, const char *, name, int, name_sz, int, flags, u64 *, res) { + *res =0 ;if (flags)return -EINVAL ;
net/core/filter.c +23 -21
87 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 292/634 perf scripts python cs-etm: Restore first sample log in verbose mode
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Clark <[email protected]>
[ Upstream commit ae8e4f4048b839c1cb333d9e3d20e634b430139e ]
The linked commit moved the early return on the first sample to before the verbose log, so move the log earlier too. Now the first sample is also logged and not skipped.
--- tools/perf/scripts/python/arm-cs-trace-disasm.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
tools/perf/scripts/python/arm-cs-trace-disasm.py +4 -5
@@ -192,17 +192,16 @@ def process_event(param_dict): ip = sample["ip"] addr = sample["addr"] + if (options.verbose == True): + print("Event type: %s" % name) + print_sample(sample) + # Initialize CPU data if it's empty, and directly return back # if this is the first tracing event for this CPU. if (cpu_data.get(str(cpu) + 'addr') == None): cpu_data[str(cpu) + 'addr'] = addr return - - if (options.verbose == True): - print("Event type: %s" % name) - print_sample(sample) - # If cannot find dso so cannot dump assembler, bail out if (dso == '[unknown]'): return
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 293/634 perf mem: Free the allocated sort string, fixing a leak
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
[ Upstream commit 3da209bb1177462b6fe8e3021a5527a5a49a9336 ]
The get_sort_order() returns either a new string (from strdup) or NULL but it never gets freed.
--- tools/perf/builtin-mem.c | 1 + 1 file changed, 1 insertion(+)
tools/perf/builtin-mem.c +1 -0
@@ -372,6 +372,7 @@ static int report_events(int argc, const char **argv, struct perf_mem *mem) rep_argv[i] = argv[j]; ret =cmd_report (i, rep_argv); +free (new_sort_order);free (rep_argv);return ret; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 294/634 perf callchain: Fix stitch LBR memory leaks
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Rogers <[email protected]>
[ Upstream commit 599c19397b17d197fc1184bbc950f163a292efc9 ]
The 'struct callchain_cursor_node' has a 'struct map_symbol' whose maps and map members are reference counted. Ensure these values use a _get routine to increment the reference counts and use map_symbol__exit() to release the reference counts.
Do similar for 'struct thread's prev_lbr_cursor, but save the size of the prev_lbr_cursor array so that it may be iterated.
Ensure that when stitch_nodes are placed on the free list the map_symbols are exited.
Fix resolve_lbr_callchain_sample() by replacing list_replace_init() to list_splice_init(), so the whole list is moved and nodes aren't leaked.
A reproduction of the memory leaks is possible with a leak sanitizer build in the perf report command of:
``` $ perf record -e cycles --call-graph lbr perf test -w thloop $ perf report --stitch-lbr ```
--- tools/perf/util/machine.c | 17 +++++++++++++++-- tools/perf/util/thread.c | 4 ++++ tools/perf/util/thread.h | 1 + 3 files changed, 20 insertions(+), 2 deletions(-)
tools/perf/util/machine.c +15 -2
@@ -2270,8 +2270,12 @@ static void save_lbr_cursor_node(struct thread *thread, cursor->curr = cursor->first; else cursor->curr = cursor->curr->next; + +map_symbol__exit (&lbr_stitch->prev_lbr_cursor[idx].ms);memcpy (&lbr_stitch->prev_lbr_cursor[idx], cursor->curr,sizeof (struct callchain_cursor_node )); + lbr_stitch->prev_lbr_cursor[idx].ms.maps =maps__get (cursor->curr->ms.maps); + lbr_stitch->prev_lbr_cursor[idx].ms.map =map__get (cursor->curr->ms.map); lbr_stitch->prev_lbr_cursor[idx].valid = true; cursor->pos++;
@@ -2482,6 +2486,9 @@ static bool has_stitched_lbr(struct thread *thread,memcpy (&stitch_node->cursor, &lbr_stitch->prev_lbr_cursor[i],sizeof (struct callchain_cursor_node )); + stitch_node->cursor.ms.maps =maps__get (lbr_stitch->prev_lbr_cursor[i].ms.maps); + stitch_node->cursor.ms.map =map__get (lbr_stitch->prev_lbr_cursor[i].ms.map); +if (callee)list_add (&stitch_node->node, &lbr_stitch->lists);else
@@ -2505,6 +2512,8 @@ static bool alloc_lbr_stitch(struct thread *thread, unsigned int max_lbr)if (!thread__lbr_stitch (thread)->prev_lbr_cursor) goto free_lbr_stitch; +thread__lbr_stitch (thread)->prev_lbr_cursor_size = max_lbr +1 ; +INIT_LIST_HEAD (&thread__lbr_stitch (thread)->lists);INIT_LIST_HEAD (&thread__lbr_stitch (thread)->free_lists);
@@ -2560,8 +2569,12 @@ static int resolve_lbr_callchain_sample(struct thread *thread, max_lbr, callee);if (!stitched_lbr && !list_empty (&lbr_stitch->lists)) { -list_replace_init (&lbr_stitch->lists, - &lbr_stitch->free_lists); +struct stitch_list *stitch_node; + +list_for_each_entry (stitch_node, &lbr_stitch->lists, node) +map_symbol__exit (&stitch_node->cursor.ms); + +list_splice_init (&lbr_stitch->lists, &lbr_stitch->free_lists); }memcpy (&lbr_stitch->prev_sample, sample,sizeof (*sample)); }
tools/perf/util/thread.c +4 -0
@@ -476,6 +476,7 @@ void thread__free_stitch_list(struct thread *thread)return ;list_for_each_entry_safe (pos, tmp, &lbr_stitch->lists, node) { +map_symbol__exit (&pos->cursor.ms);list_del_init (&pos->node);free (pos); }
@@ -485,6 +486,9 @@ void thread__free_stitch_list(struct thread *thread)free (pos); } +for (unsigned int i =0 ; i < lbr_stitch->prev_lbr_cursor_size; i++) +map_symbol__exit (&lbr_stitch->prev_lbr_cursor[i].ms); +zfree (&lbr_stitch->prev_lbr_cursor);free (thread__lbr_stitch (thread));thread__set_lbr_stitch (thread,NULL );
tools/perf/util/thread.h +1 -0
@@ -26,6 +26,7 @@ struct lbr_stitch {struct list_head free_lists;struct perf_sample prev_sample;struct callchain_cursor_node *prev_lbr_cursor; +unsigned int prev_lbr_cursor_size; };DECLARE_RC_STRUCT (thread) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 295/634 perf lock contention: Change stack_id type to s32
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
[ Upstream commit 040c0f887fdcfe747a3f63c94e9cd29e9ed0b872 ]
The bpf_get_stackid() helper returns a signed type to check whether it failed to get a stacktrace or not. But it saved the result in u32 and checked if the value is negative.
376 if (needs_callstack) {
377 pelem->stack_id = bpf_get_stackid(ctx, &stacks,
378 BPF_F_FAST_STACK_CMP | stack_skip); --> 379 if (pelem->stack_id < 0)
./tools/perf/util/bpf_skel/lock_contention.bpf.c:379 contention_begin()
warn: unsigned 'pelem->stack_id' is never less than zero.
Let's change the type to s32 instead.
--- tools/perf/util/bpf_skel/lock_data.h | 4 ++-- tools/perf/util/bpf_skel/vmlinux/vmlinux.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-)
tools/perf/util/bpf_skel/lock_data.h +2 -2
@@ -7,11 +7,11 @@ struct tstamp_data {u64 timestamp;u64 lock;u32 flags; -u32 stack_id; +s32 stack_id; };struct contention_key { -u32 stack_id; +s32 stack_id;u32 pid;u64 lock_addr_or_cgroup; };
tools/perf/util/bpf_skel/vmlinux/vmlinux.h +1 -0
@@ -15,6 +15,7 @@typedef __u8 u8 ;typedef __u32 u32 ; +typedef __s32 s32 ;typedef __u64 u64 ;typedef __s64 s64 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 296/634 perf inject: Fix leader sampling inserting additional samples
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Rogers <[email protected]>
[ Upstream commit 79bcd34e0f3da39fda841406ccc957405e724852 ]
The processing of leader samples would turn an individual sample with a group of read values into multiple samples. 'perf inject' would pass through the additional samples increasing the output data file size:
$ perf record -g -e "{instructions,cycles}:S" -o perf.orig.data true
$ perf script -D -i perf.orig.data | sed -e 's/perf.orig.data/perf.data/g' > orig.txt
$ perf inject -i perf.orig.data -o perf.new.data
$ perf script -D -i perf.new.data | sed -e 's/perf.new.data/perf.data/g' > new.txt
$ diff -u orig.txt new.txt
--- orig.txt 2024-07-29 14:29:40.606576769 -0700
+++ new.txt 2024-07-29 14:30:04.142737434 -0700
...
[email protected] [0x30]: event: 3
[email protected] [0xd0]: event: 9
+.
+. ... raw event: size 208 bytes
+. 0000: 09 00 00 00 01 00 d0 00 fc 72 01 86 ff ff ff ff .........r......
+. 0010: 74 7d 2c 00 74 7d 2c 00 fb c3 79 f9 ba d5 05 00 t},.t},...y.....
+. 0020: e6 cb 1a 00 00 00 00 00 01 00 00 00 00 00 00 00 ................
+. 0030: 02 00 00 00 00 00 00 00 76 01 00 00 00 00 00 00 ........v.......
+. 0040: e6 cb 1a 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+. 0050: 62 18 00 00 00 00 00 00 f6 cb 1a 00 00 00 00 00 b...............
+. 0060: 00 00 00 00 00 00 00 00 0c 00 00 00 00 00 00 00 ................
+. 0070: 80 ff ff ff ff ff ff ff fc 72 01 86 ff ff ff ff .........r......
+. 0080: f3 0e 6e 85 ff ff ff ff 0c cb 7f 85 ff ff ff ff ..n.............
+. 0090: bc f2 87 85 ff ff ff ff 44 af 7f 85 ff ff ff ff ........D.......
+. 00a0: bd be 7f 85 ff ff ff ff 26 d0 7f 85 ff ff ff ff ........&.......
+. 00b0: 6d a4 ff 85 ff ff ff ff ea 00 20 86 ff ff ff ff m......... .....
+. 00c0: 00 fe ff ff ff ff ff ff 57 14 4f 43 fc 7e 00 00 ........W.OC.~..
+
+1642373909693435 0xc550 [0xd0]: PERF_RECORD_SAMPLE(IP, 0x1): 2915700/2915700: 0xffffffff860172fc period: 1 addr: 0
+... FP chain: nr:12
+..... 0: ffffffffffffff80
+..... 1: ffffffff860172fc
+..... 2: ffffffff856e0ef3
+..... 3: ffffffff857fcb0c
+..... 4: ffffffff8587f2bc
+..... 5: ffffffff857faf44
+..... 6: ffffffff857fbebd
+..... 7: ffffffff857fd026
+..... 8: ffffffff85ffa46d
+..... 9: ffffffff862000ea
+..... 10: fffffffffffffe00
+..... 11: 00007efc434f1457
+... sample_read:
+.... group nr 2
+..... id 00000000001acbe6, value 0000000000000176, lost 0
+..... id 00000000001acbf6, value 0000000000001862, lost 0
+
[email protected] [0x30]: event: 3
...This behavior is incorrect as in the case above 'perf inject' should have done nothing. Fix this behavior by disabling separating samples for a tool that requests it. Only request this for perf inject so as to not affect other perf tools. With the patch and the test above there are no differences between the orig.txt and new.txt.
--- tools/perf/builtin-inject.c | 1 + tools/perf/util/session.c | 3 +++ tools/perf/util/tool.h | 1 + 3 files changed, 5 insertions(+)
tools/perf/builtin-inject.c +1 -0
@@ -2204,6 +2204,7 @@ int cmd_inject(int argc, const char **argv) .finished_init = perf_event__repipe_op2_synth, .compressed = perf_event__repipe_op4_synth, .auxtrace = perf_event__repipe_auxtrace, + .dont_split_sample_group = true, }, .input_name = "-", .samples = LIST_HEAD_INIT(inject.samples),
tools/perf/util/session.c +3 -0
@@ -1511,6 +1511,9 @@ static int deliver_sample_group(struct evlist *evlist,int ret = -EINVAL ;struct sample_read_value *v = sample->read.group.values; +if (tool->dont_split_sample_group) +return deliver_sample_value (evlist, tool, event, sample, v, machine); +sample_read_group__for_each (v, sample->read.group.nr, read_format) { ret =deliver_sample_value (evlist, tool, event, sample, v, machine);
tools/perf/util/tool.h +1 -0
@@ -85,6 +85,7 @@ struct perf_tool {bool namespace_events;bool cgroup_events;bool no_warn; +bool dont_split_sample_group;enum show_feature_header show_feat_hdr; };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 297/634 perf report: Fix --total-cycles --stdio output error
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kan Liang <[email protected]>
[ Upstream commit 3ef44458071a19e5b5832cdfe6f75273aa521b6e ]
The --total-cycles may output wrong information with the --stdio.
For example:
# perf record -e "{cycles,instructions}",cache-misses -b sleep 1
# perf report --total-cycles --stdioThe total cycles output of {cycles,instructions} and cache-misses are almost the same.
# Samples: 938 of events 'anon group { cycles, instructions }' # Event count (approx.): 938
#
# Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles [Program Block Range]
# ............... .............. ........... .......... ..................................................>
#
11.19% 2.6K 0.10% 21 [perf_iterate_ctx+48 -> >
5.79% 1.4K 0.45% 97 [__intel_pmu_enable_all.constprop.0+80 -> __intel_>
5.11% 1.2K 0.33% 71 [native_write_msr+0 ->> # Samples: 293 of event 'cache-misses'
# Event count (approx.): 293
#
# Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles [Program Block Range]
# ............... .............. ........... .......... ..................................................>
#
11.19% 2.6K 0.13% 21 [perf_iterate_ctx+48 -> >
5.79% 1.4K 0.59% 97 [__intel_pmu_enable_all.constprop.0+80 -> __intel_>
5.11% 1.2K 0.43% 71 [native_write_msr+0 ->>With the symbol_conf.event_group, the 'perf report' should only report the block information of the leader event in a group.
However, the current implementation retrieves the next event's block information, rather than the next group leader's block information.
Make sure the index is updated even if the event is skipped.
With the patch,
# Samples: 293 of event 'cache-misses'
# Event count (approx.): 293
#
# Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles [Program Block Range]
# ............... .............. ........... .......... ..................................................>
#
37.98% 9.0K 4.05% 299 [perf_event_addr_filters_exec+0 -> perf_event_a>
11.19% 2.6K 0.28% 21 [perf_iterate_ctx+48 -> >
5.79% 1.4K 1.32% 97 [__intel_pmu_enable_all.constprop.0+80 -> __intel_>--- tools/perf/builtin-report.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/perf/builtin-report.c +2 -1
@@ -565,6 +565,7 @@ static int evlist__tty_browse_hists(struct evlist *evlist, struct report *rep, cstruct hists *hists =evsel__hists (pos);const char *evname =evsel__name (pos); + i++;if (symbol_conf.event_group && !evsel__is_group_leader (pos))continue ;
@@ -574,7 +575,7 @@ static int evlist__tty_browse_hists(struct evlist *evlist, struct report *rep, chists__fprintf_nr_sample_events (hists, rep, evname, stdout);if (rep->total_cycles_mode) { -report__browse_block_hists (&rep->block_reports[i++].hist, +report__browse_block_hists (&rep->block_reports[i -1 ].hist, rep->min_percent, pos,NULL );continue ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 298/634 perf build: Fix up broken capstone feature detection fast path
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
[ Upstream commit 4c55560f23d19051adc7e76818687a88448bef83 ]
The capstone devel headers define 'struct bpf_insn' in a way that clashes with what is in the libbpf devel headers, so we so far need to avoid including both.
This is happening on the tools/build/feature/test-all.c file, where we try building all the expected set of libraries to be normally available on a system:
⬢[acme@toolbox perf-tools-next]$ cat /tmp/build/perf-tools-next/feature/test-all.make.output In file included from test-bpf.c:3,
from test-all.c:150:
/home/acme/git/perf-tools-next/tools/include/uapi/linux/bpf.h:77:8: error: ‘bpf_insn’ defined as wrong kind of tag
77 | struct bpf_insn {
| ^~~~~~~~ ⬢[acme@toolbox perf-tools-next]$ cat /tmp/build/perf-tools-next/feature/test-all.make.output
When doing so there is a trick where we define main to be main_test_libcapstone, then include the individual tools/build/feture/test-libcapstone.c capability query test, and then we undef 'main' because we'll do it all over again with the next expected library to be tested (at this time 'lzma').
To complete this mechanism we need to, in test-all.c 'main' routine, to call main_test_libcapstone(), which isn't being done, so the effect of adding references to capstone in test-all.c are not achieved.
The only thing that is happening is that test-all.c is failing to build and thus all the tests will have to be done individually, which nullifies the test-all.c single build speedup.
So lets remove references to capstone from test-all.c to see if this makes it build again so that we get faster builds or go on fixing up whatever is preventing us to get that benefit.
Nothing: after this fix we get a clean test-all.c build and get the build speedup back:
⬢[acme@toolbox perf-tools-next]$ cat /tmp/build/perf-tools-next/feature/test-all.make.output ⬢[acme@toolbox perf-tools-next]$ cat /tmp/build/perf-tools-next/feature/test-all.
test-all.bin test-all.d test-all.make.output
⬢[acme@toolbox perf-tools-next]$ cat /tmp/build/perf-tools-next/feature/test-all.make.output ⬢[acme@toolbox perf-tools-next]$ ldd /tmp/build/perf-tools-next/feature/test-all.bin
linux-vdso.so.1 (0x00007f13277a1000)
libpython3.12.so.1.0 => /lib64/libpython3.12.so.1.0 (0x00007f1326e00000) libm.so.6 => /lib64/libm.so.6 (0x00007f13274be000)
libtraceevent.so.1 => /lib64/libtraceevent.so.1 (0x00007f1327496000) libtracefs.so.1 => /lib64/libtracefs.so.1 (0x00007f132746f000) libcrypto.so.3 => /lib64/libcrypto.so.3 (0x00007f1326800000) libunwind-x86_64.so.8 => /lib64/libunwind-x86_64.so.8 (0x00007f1327452000) libunwind.so.8 => /lib64/libunwind.so.8 (0x00007f1327436000) liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f1327403000)
libdw.so.1 => /lib64/libdw.so.1 (0x00007f1326d6f000)
libz.so.1 => /lib64/libz.so.1 (0x00007f13273e2000)
libelf.so.1 => /lib64/libelf.so.1 (0x00007f1326d53000)
libnuma.so.1 => /lib64/libnuma.so.1 (0x00007f13273d4000)
libslang.so.2 => /lib64/libslang.so.2 (0x00007f1326400000) libperl.so.5.38 => /lib64/libperl.so.5.38 (0x00007f1326000000) libc.so.6 => /lib64/libc.so.6 (0x00007f1325e0f000)
libzstd.so.1 => /lib64/libzstd.so.1 (0x00007f1326741000) /lib64/ld-linux-x86-64.so.2 (0x00007f13277a3000)
libbz2.so.1 => /lib64/libbz2.so.1 (0x00007f1326d3f000)
libcrypt.so.2 => /lib64/libcrypt.so.2 (0x00007f1326d07000)
⬢[acme@toolbox perf-tools-next]$
And when having capstone-devel installed we get it detected and linked with perf, allowing us to benefit from the features that it enables:
⬢[acme@toolbox perf-tools-next]$ rpm -q capstone-devel capstone-devel-5.0.1-3.fc40.x86_64
⬢[acme@toolbox perf-tools-next]$ ldd /tmp/build/perf-tools-next/perf | grep capstone
libcapstone.so.5 => /lib64/libcapstone.so.5 (0x00007fe6a5c00000)
⬢[acme@toolbox perf-tools-next]$ /tmp/build/perf-tools-next/perf -vv | grep cap
libcapstone: [ on ] # HAVE_LIBCAPSTONE_SUPPORT
⬢[acme@toolbox perf-tools-next]$
--- tools/build/feature/test-all.c | 4 ---- 1 file changed, 4 deletions(-)
tools/build/feature/test-all.c +0 -4
@@ -134,10 +134,6 @@#undef main#endif -#define main main_test_libcapstone -# include "test-libcapstone.c" -#undef main -#define main main_test_lzma# include "test-lzma.c" #undef main
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 299/634 perf sched timehist: Fix missing free of session in perf_sched__timehist()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Jihong <[email protected]>
[ Upstream commit 6bdf5168b6fb19541b0c1862bdaa596d116c7bfb ]
When perf_time__parse_str() fails in perf_sched__timehist(), need to free session that was previously created, fix it.
--- tools/perf/builtin-sched.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/perf/builtin-sched.c +2 -1
@@ -3031,7 +3031,8 @@ static int perf_sched__timehist(struct perf_sched *sched)if (perf_time__parse_str (&sched->ptime, sched->time_str) !=0 ) {pr_err ("Invalid time string\n" ); -return -EINVAL ; + err = -EINVAL ; + goto out; }if (timehist_check_attr (sched, evlist) !=0 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 300/634 perf stat: Display iostat headers correctly
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yicong Yang <[email protected]>
[ Upstream commit 2615639352420e6e3115952c5b8f46846e1c6d0e ]
Currently we'll only print metric headers for metric leader in aggregration mode. This will make perf iostat header not shown since it'll aggregrated globally but don't have metric events:
root@ubuntu204:/home/yang/linux/tools/perf# ./perf stat --iostat --timeout 1000
Performance counter stats for 'system wide':
port
0000:00 0 0 0 0
0000:80 0 0 0 0
[...]Fix this by excluding the iostat in the check of printing metric headers. Then we can see the headers:
root@ubuntu204:/home/yang/linux/tools/perf# ./perf stat --iostat --timeout 1000
Performance counter stats for 'system wide':
port Inbound Read(MB) Inbound Write(MB) Outbound Read(MB) Outbound Write(MB)
0000:00 0 0 0 0
0000:80 0 0 0 0
[...]--- tools/perf/util/stat-display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/perf/util/stat-display.c +2 -1
@@ -1226,7 +1226,8 @@ static void print_metric_headers(struct perf_stat_config *config,/* Print metrics headers only */ evlist__for_each_entry (evlist, counter) { -if (config->aggr_mode !=AGGR_NONE && counter->metric_leader != counter) +if (!config->iostat_run && + config->aggr_mode !=AGGR_NONE && counter->metric_leader != counter)continue ; os.evsel = counter;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 301/634 perf dwarf-aux: Check allowed location expressions when collecting variables
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
[ Upstream commit e8bb03ed6850c6ed4ce2f1600ea73401fc2ebd95 ]
It missed to call check_allowed_ops() in __die_collect_vars_cb() so it can take variables with complex location expression incorrectly.
For example, I found some variable has this expression.
015d8df8 ffffffff81aacfb3 (base address)
015d8e01 v000000000000004 v000000000000000 views at 015d8df2 for:
ffffffff81aacfb3 ffffffff81aacfd2 (DW_OP_fbreg: -176; DW_OP_deref;
DW_OP_plus_uconst: 332; DW_OP_deref_size: 4;
DW_OP_lit1; DW_OP_shra; DW_OP_const1u: 64;
DW_OP_minus; DW_OP_stack_value)
015d8e14 v000000000000000 v000000000000000 views at 015d8df4 for:
ffffffff81aacfd2 ffffffff81aacfd7 (DW_OP_reg3 (rbx))
015d8e19 v000000000000000 v000000000000000 views at 015d8df6 for:
ffffffff81aacfd7 ffffffff81aad020 (DW_OP_fbreg: -176; DW_OP_deref;
DW_OP_plus_uconst: 332; DW_OP_deref_size: 4;
DW_OP_lit1; DW_OP_shra; DW_OP_const1u: 64;
DW_OP_minus; DW_OP_stack_value)
015d8e2c <End of list>It looks like '((int *)(-176(%rbp) + 332) >> 1) - 64' but the current code thought it's just -176(%rbp) and processed the variable incorrectly. It should reject such a complex expression if check_allowed_ops() doesn't like it. :)
--- tools/perf/util/dwarf-aux.c | 3 +++ 1 file changed, 3 insertions(+)
tools/perf/util/dwarf-aux.c +3 -0
@@ -1598,6 +1598,9 @@ static int __die_collect_vars_cb(Dwarf_Die *die_mem, void *arg)if (dwarf_getlocations (&attr,0 , &base, &start, &end, &ops, &nops) <=0 )return DIE_FIND_CB_SIBLING ; +if (!check_allowed_ops (ops, nops)) +return DIE_FIND_CB_SIBLING ; +if (die_get_real_type (die_mem, &type_die) ==NULL )return DIE_FIND_CB_SIBLING ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 302/634 perf annotate-data: Fix off-by-one in location range check
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
[ Upstream commit 3ab0b8b238b5130ae3fa37ddaa329fc0e93b6b9a ]
The location list will have entries with half-open addressing like [start, end) which means it doesn't include the end address. So it should skip entries at the end address and match to the next entry.
An example location list looks like this (from readelf -wo):
00237876 ffffffff8110d32b (base address)
0023787f v000000000000000 v000000000000002 views at 00237868 for:
ffffffff8110d32b ffffffff8110d4eb (DW_OP_reg3 (rbx)) <<<--- 1
00237885 v000000000000002 v000000000000000 views at 0023786a for:
ffffffff8110d4eb ffffffff8110d50b (DW_OP_reg14 (r14)) <<<--- 2
0023788c v000000000000000 v000000000000001 views at 0023786c for:
ffffffff8110d50b ffffffff8110d7c4 (DW_OP_reg3 (rbx))
00237893 v000000000000000 v000000000000000 views at 0023786e for:
ffffffff8110d806 ffffffff8110d854 (DW_OP_reg3 (rbx))
0023789a v000000000000000 v000000000000000 views at 00237870 for:
ffffffff8110d876 ffffffff8110d88e (DW_OP_reg3 (rbx))The first entry at 0023787f has [8110d32b, 8110d4eb) (omitting the ffffffff at the beginning), and the second one has [8110d4eb, 8110d50b).
--- tools/perf/util/annotate-data.c | 2 +- tools/perf/util/dwarf-aux.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
tools/perf/util/annotate-data.c +1 -1
@@ -104,7 +104,7 @@ static void pr_debug_location(Dwarf_Die *die, u64 pc, int reg)return ;while ((off =dwarf_getlocations (&attr, off, &base, &start, &end, &ops, &nops)) >0 ) { -if (reg !=DWARF_REG_PC && end < pc) +if (reg !=DWARF_REG_PC && end <= pc)continue ;if (reg !=DWARF_REG_PC && start > pc)break ;
tools/perf/util/dwarf-aux.c +1 -1
@@ -1444,7 +1444,7 @@ static int __die_find_var_reg_cb(Dwarf_Die *die_mem, void *arg)while ((off =dwarf_getlocations (&attr, off, &base, &start, &end, &ops, &nops)) >0 ) {/* Assuming the location list is sorted by address */ -if (end < data->pc) +if (end <= data->pc)continue ;if (start > data->pc)break ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 303/634 perf dwarf-aux: Handle bitfield members from pointer access
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
[ Upstream commit a11b4222bb579dcf9646f3c4ecd2212ae762a2c8 ]
The __die_find_member_offset_cb() missed to handle bitfield members which don't have DW_AT_data_member_location. Like in adding member types in __add_member_cb() it should fallback to check the bit offset when it resolves the member type for an offset.
--- tools/perf/util/dwarf-aux.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
tools/perf/util/dwarf-aux.c +9 -2
@@ -1977,8 +1977,15 @@ static int __die_find_member_offset_cb(Dwarf_Die *die_mem, void *arg)return DIE_FIND_CB_SIBLING ;/* Unions might not have location */ -if (die_get_data_member_location (die_mem, &loc) <0 ) - loc =0 ; +if (die_get_data_member_location (die_mem, &loc) <0 ) { +Dwarf_Attribute attr; + +if (dwarf_attr_integrate (die_mem, DW_AT_data_bit_offset, &attr) && +dwarf_formudata (&attr, &loc) ==0 ) + loc /=8 ; +else + loc =0 ; + }if (offset == loc)return DIE_FIND_CB_END ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 304/634 perf sched timehist: Fixed timestamp error when unable to confirm event sched_in time
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Jihong <[email protected]>
[ Upstream commit 39c243411bdb8fb35777adf49ee32549633c4e12 ]
If sched_in event for current task is not recorded, sched_in timestamp will be set to end_time of time window interest, causing an error in timestamp show. In this case, we choose to ignore this event.
Test scenario:
perf[1229608] does not record the first sched_in event, run time and sch delay are both 0
# perf sched timehist
Samples of sched_switch event do not have callchains.
time cpu task name wait time sch delay run time
[tid/pid] (msec) (msec) (msec)
--------------- ------ ------------------------------ --------- --------- ---------
2090450.763231 [0000] perf[1229608] 0.000 0.000 0.000
2090450.763235 [0000] migration/0[15] 0.000 0.001 0.003
2090450.763263 [0001] perf[1229608] 0.000 0.000 0.000
2090450.763268 [0001] migration/1[21] 0.000 0.001 0.004
2090450.763302 [0002] perf[1229608] 0.000 0.000 0.000
2090450.763309 [0002] migration/2[27] 0.000 0.001 0.007
2090450.763338 [0003] perf[1229608] 0.000 0.000 0.000
2090450.763343 [0003] migration/3[33] 0.000 0.001 0.004Before:
arbitrarily specify a time window of interest, timestamp will be set to an incorrect value
# perf sched timehist --time 100,200
Samples of sched_switch event do not have callchains.
time cpu task name wait time sch delay run time
[tid/pid] (msec) (msec) (msec)
--------------- ------ ------------------------------ --------- --------- ---------
200.000000 [0000] perf[1229608] 0.000 0.000 0.000
200.000000 [0001] perf[1229608] 0.000 0.000 0.000
200.000000 [0002] perf[1229608] 0.000 0.000 0.000
200.000000 [0003] perf[1229608] 0.000 0.000 0.000
200.000000 [0004] perf[1229608] 0.000 0.000 0.000
200.000000 [0005] perf[1229608] 0.000 0.000 0.000
200.000000 [0006] perf[1229608] 0.000 0.000 0.000
200.000000 [0007] perf[1229608] 0.000 0.000 0.000After:
# perf sched timehist --time 100,200
Samples of sched_switch event do not have callchains.
time cpu task name wait time sch delay run time
[tid/pid] (msec) (msec) (msec)
--------------- ------ ------------------------------ --------- --------- ------------ tools/perf/builtin-sched.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
tools/perf/builtin-sched.c +4 -1
@@ -2596,9 +2596,12 @@ static int timehist_sched_change_event(struct perf_tool *tool,* - previous sched event is out of window - we are done * - sample time is beyond window user cares about - reset it * to close out stats for time window interest +* - If tprev is 0, that is, sched_in event for current task is +* not recorded, cannot determine whether sched_in event is +* within time window interest - ignore it */ if (ptime->end) { -if (tprev > ptime->end) +if (!tprev || tprev > ptime->end) goto out;if (t > ptime->end)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 305/634 perf time-utils: Fix 32-bit nsec parsing
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Rogers <[email protected]>
[ Upstream commit 38e2648a81204c9fc5b4c87a8ffce93a6ed91b65 ]
The "time utils" test fails in 32-bit builds:
...
parse_nsec_time("18446744073.709551615")
Failed. ptime 4294967295709551615 expected 18446744073709551615
...
Switch strtoul to strtoull as an unsigned long in 32-bit build isn't 64-bits.
--- tools/perf/util/time-utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/util/time-utils.c +2 -2
@@ -20,7 +20,7 @@ int parse_nsec_time(const char *str, u64 *ptime)u64 time_sec, time_nsec;char *end; - time_sec =strtoul (str, &end,10 ); + time_sec =strtoull (str, &end,10 );if (*end !='.' && *end !='\0' )return -1 ;
@@ -38,7 +38,7 @@ int parse_nsec_time(const char *str, u64 *ptime)for (i =strlen (nsec_buf); i <9 ; i++) nsec_buf[i] ='0' ; - time_nsec =strtoul (nsec_buf, &end,10 ); + time_nsec =strtoull (nsec_buf, &end,10 );if (*end !='\0' )return -1 ; }else
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 306/634 perf mem: Check mem_events for all eligible PMUs
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kan Liang <[email protected]>
[ Upstream commit 6e05d28ff232cf445cc6ae59336b7f2081ef9b96 ]
The current perf_pmu__mem_events_init() only checks the availability of the mem_events for the first eligible PMU. It works for non-hybrid machines and hybrid machines that have the same mem_events.
However, it may bring issues if a hybrid machine has a different mem_events on different PMU, e.g., Alder Lake and Raptor Lake. A mem-loads-aux event is only required for the p-core. The mem_events on both e-core and p-core should be checked and marked.
The issue was not found, because it's hidden by another bug, which only records the mem-events for the e-core. The wrong check for the p-core events didn't yell.
--- tools/perf/builtin-c2c.c | 2 +- tools/perf/builtin-mem.c | 2 +- tools/perf/util/mem-events.c | 14 +++++++++++++- tools/perf/util/mem-events.h | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-)
tools/perf/builtin-c2c.c +1 -1
@@ -3266,7 +3266,7 @@ static int perf_c2c__record(int argc, const char **argv)return -1 ; } -if (perf_pmu__mem_events_init (pmu)) { +if (perf_pmu__mem_events_init ()) {pr_err ("failed: memory events not supported\n" );return -1 ; }
tools/perf/builtin-mem.c +1 -1
@@ -97,7 +97,7 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)return -1 ; } -if (perf_pmu__mem_events_init (pmu)) { +if (perf_pmu__mem_events_init ()) {pr_err ("failed: memory events not supported\n" );return -1 ; }
tools/perf/util/mem-events.c +13 -1
@@ -191,7 +191,7 @@ static bool perf_pmu__mem_events_supported(const char *mnt, struct perf_pmu *pmureturn !stat (path, &st); } -int perf_pmu__mem_events_init (struct perf_pmu *pmu) +static int __perf_pmu__mem_events_init (struct perf_pmu *pmu) {const char *mnt =sysfs__mount ();bool found = false;
@@ -218,6 +218,18 @@ int perf_pmu__mem_events_init(struct perf_pmu *pmu)return found ?0 : -ENOENT ; } +int perf_pmu__mem_events_init (void ) +{ +struct perf_pmu *pmu =NULL ; + +while ((pmu =perf_pmus__scan_mem (pmu)) !=NULL ) { +if (__perf_pmu__mem_events_init (pmu)) +return -ENOENT ; + } + +return 0 ; +} +void perf_pmu__mem_events_list (struct perf_pmu *pmu) {int j;
tools/perf/util/mem-events.h +1 -1
@@ -30,7 +30,7 @@ extern unsigned int perf_mem_events__loads_ldlat;extern struct perf_mem_event perf_mem_events[PERF_MEM_EVENTS__MAX ];int perf_pmu__mem_events_parse (struct perf_pmu *pmu,const char *str); -int perf_pmu__mem_events_init (struct perf_pmu *pmu); +int perf_pmu__mem_events_init (void );struct perf_mem_event *perf_pmu__mem_events_ptr (struct perf_pmu *pmu,int i);struct perf_pmu *perf_mem_events_find_pmu (void );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 307/634 perf mem: Fix missed p-core mem events on ADL and RPL
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kan Liang <[email protected]>
[ Upstream commit 5ad7db2c3f941cde3045ce38a9c4c40b0c7d56b9 ]
The p-core mem events are missed when launching 'perf mem record' on ADL and RPL.
root@number:~# perf mem record sleep 1 Memory events are enabled on a subset of CPUs: 16-27 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.032 MB perf.data ] root@number:~# perf evlist cpu_atom/mem-loads,ldlat=30/P cpu_atom/mem-stores/P dummy:u
A variable 'record' in the 'struct perf_mem_event' is to indicate whether a mem event in a mem_events[] should be recorded. The current code only configure the variable for the first eligible PMU.
It's good enough for a non-hybrid machine or a hybrid machine which has the same mem_events[].
However, if a different mem_events[] is used for different PMUs on a hybrid machine, e.g., ADL or RPL, the 'record' for the second PMU never get a chance to be set.
The mem_events[] of the second PMU are always ignored.
'perf mem' doesn't support the per-PMU configuration now. A per-PMU mem_events[] 'record' variable doesn't make sense. Make it global.
That could also avoid searching for the per-PMU mem_events[] via perf_pmu__mem_events_ptr every time.
Committer testing:
root@number:~# perf evlist -g
cpu_atom/mem-loads,ldlat=30/P
cpu_atom/mem-stores/P
{cpu_core/mem-loads-aux/,cpu_core/mem-loads,ldlat=30/}
cpu_core/mem-stores/P
dummy:u
root@number:~#The :S for '{cpu_core/mem-loads-aux/,cpu_core/mem-loads,ldlat=30/}' is not being added by 'perf evlist -g', to be checked.
--- tools/perf/builtin-c2c.c | 12 ++++-------- tools/perf/builtin-mem.c | 17 ++++++----------- tools/perf/util/mem-events.c | 6 ++++-- tools/perf/util/mem-events.h | 2 +- 4 files changed, 15 insertions(+), 22 deletions(-)
tools/perf/builtin-c2c.c +4 -8
@@ -3290,19 +3290,15 @@ static int perf_c2c__record(int argc, const char **argv)* PERF_MEM_EVENTS__LOAD_STORE if it is supported. */ if (e->tag) { - e->record = true; + perf_mem_record[PERF_MEM_EVENTS__LOAD_STORE ] = true; rec_argv[i++] ="-W" ; }else { - e =perf_pmu__mem_events_ptr (pmu,PERF_MEM_EVENTS__LOAD ); - e->record = true; - - e =perf_pmu__mem_events_ptr (pmu,PERF_MEM_EVENTS__STORE ); - e->record = true; + perf_mem_record[PERF_MEM_EVENTS__LOAD ] = true; + perf_mem_record[PERF_MEM_EVENTS__STORE ] = true; } } - e =perf_pmu__mem_events_ptr (pmu,PERF_MEM_EVENTS__LOAD ); -if (e->record) +if (perf_mem_record[PERF_MEM_EVENTS__LOAD ]) rec_argv[i++] ="-W" ; rec_argv[i++] ="-d" ;
tools/perf/builtin-mem.c +6 -11
@@ -126,22 +126,17 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)if (e->tag && (mem->operation &MEM_OPERATION_LOAD ) && (mem->operation &MEM_OPERATION_STORE )) { - e->record = true; + perf_mem_record[PERF_MEM_EVENTS__LOAD_STORE ] = true; rec_argv[i++] ="-W" ; }else { -if (mem->operation &MEM_OPERATION_LOAD ) { - e =perf_pmu__mem_events_ptr (pmu,PERF_MEM_EVENTS__LOAD ); - e->record = true; - } +if (mem->operation &MEM_OPERATION_LOAD ) + perf_mem_record[PERF_MEM_EVENTS__LOAD ] = true; -if (mem->operation &MEM_OPERATION_STORE ) { - e =perf_pmu__mem_events_ptr (pmu,PERF_MEM_EVENTS__STORE ); - e->record = true; - } +if (mem->operation &MEM_OPERATION_STORE ) + perf_mem_record[PERF_MEM_EVENTS__STORE ] = true; } - e =perf_pmu__mem_events_ptr (pmu,PERF_MEM_EVENTS__LOAD ); -if (e->record) +if (perf_mem_record[PERF_MEM_EVENTS__LOAD ]) rec_argv[i++] ="-W" ; rec_argv[i++] ="-d" ;
tools/perf/util/mem-events.c +4 -2
@@ -28,6 +28,8 @@ struct perf_mem_event perf_mem_events[PERF_MEM_EVENTS__MAX] = { };#undef E +bool perf_mem_record[PERF_MEM_EVENTS__MAX ] = {0 }; +static char mem_loads_name[100 ];static char mem_stores_name[100 ];
@@ -162,7 +164,7 @@ int perf_pmu__mem_events_parse(struct perf_pmu *pmu, const char *str)continue ;if (strstr (e->tag, tok)) - e->record = found = true; + perf_mem_record[j] = found = true; } tok =strtok_r (NULL ,"," , &saveptr);
@@ -259,7 +261,7 @@ int perf_mem_events__record_args(const char **rec_argv, int *argv_nr)for (int j =0 ; j <PERF_MEM_EVENTS__MAX ; j++) { e =perf_pmu__mem_events_ptr (pmu, j); -if (!e->record) +if (!perf_mem_record[j])continue ;if (!e->supported) {
tools/perf/util/mem-events.h +1 -1
@@ -6,7 +6,6 @@#include <linux/types.h> struct perf_mem_event { -bool record;bool supported;bool ldlat;u32 aux_event;
@@ -28,6 +27,7 @@ struct perf_pmu;extern unsigned int perf_mem_events__loads_ldlat;extern struct perf_mem_event perf_mem_events[PERF_MEM_EVENTS__MAX ]; +extern bool perf_mem_record[PERF_MEM_EVENTS__MAX ];int perf_pmu__mem_events_parse (struct perf_pmu *pmu,const char *str);int perf_pmu__mem_events_init (void );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 308/634 clk: imx: clk-audiomix: Correct parent clock for earc_phy and audpll
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit d40371a1c963db688b37826adaf5ffdafb0862a1 ]
According to Reference Manual of i.MX8MP
The parent clock of "earc_phy" is "sai_pll_out_div2", The parent clock of "audpll" is "osc_24m".
Add CLK_GATE_PARENT() macro for usage of specifying parent clock.
--- drivers/clk/imx/clk-imx8mp-audiomix.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/clk/imx/clk-imx8mp-audiomix.c +11 -2
@@ -154,6 +154,15 @@ static const struct clk_parent_data clk_imx8mp_audiomix_pll_bypass_sels[] = { PDM_SEL, 2, 0 \ } +#define CLK_GATE_PARENT (gname, cname, pname) \ + { \ + gname"_cg", \ + IMX8MP_CLK_AUDIOMIX_##cname, \ + { .fw_name = pname, .name = pname }, NULL, 1, \ + CLKEN0 + 4 * !!(IMX8MP_CLK_AUDIOMIX_##cname / 32), \ + 1, IMX8MP_CLK_AUDIOMIX_##cname % 32 \ + } +struct clk_imx8mp_audiomix_sel {const char *name;int clkid;
@@ -171,14 +180,14 @@ static struct clk_imx8mp_audiomix_sel sels[] = {CLK_GATE ("earc" ,EARC_IPG ),CLK_GATE ("ocrama" ,OCRAMA_IPG ),CLK_GATE ("aud2htx" ,AUD2HTX_IPG ), -CLK_GATE ("earc_phy" ,EARC_PHY ), +CLK_GATE_PARENT ("earc_phy" ,EARC_PHY ,"sai_pll_out_div2" ),CLK_GATE ("sdma2" ,SDMA2_ROOT ),CLK_GATE ("sdma3" ,SDMA3_ROOT ),CLK_GATE ("spba2" ,SPBA2_ROOT ),CLK_GATE ("dsp" ,DSP_ROOT ),CLK_GATE ("dspdbg" ,DSPDBG_ROOT ),CLK_GATE ("edma" ,EDMA_ROOT ), -CLK_GATE ("audpll" ,AUDPLL_ROOT ), +CLK_GATE_PARENT ("audpll" ,AUDPLL_ROOT ,"osc_24m" ),CLK_GATE ("mu2" ,MU2_ROOT ),CLK_GATE ("mu3" ,MU3_ROOT ), CLK_PDM,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 309/634 clk: imx: imx6ul: fix default parent for enet*_ref_sel
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastien Laveze <[email protected]>
[ Upstream commit e52fd71333b4ed78fd5bb43094bdc46476614d25 ]
The clk_set_parent for "enet1_ref_sel" and "enet2_ref_sel" are incorrect, therefore the original requirements to have "enet_clk_ref" as output sourced by iMX ENET PLL as a default config is not met.
Only "enet[1,2]_ref_125m" "enet[1,2]_ref_pad" are possible parents for "enet1_ref_sel" and "enet2_ref_sel".
This was observed as a regression using a custom device tree which was expecting this default config.
This can be fixed at the device tree level but having a default config matching the original behavior (before refclock mux) will avoid breaking existing configs.
--- drivers/clk/imx/clk-imx6ul.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/imx/clk-imx6ul.c +2 -2
@@ -542,8 +542,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)clk_set_parent (hws[IMX6UL_CLK_ENFC_SEL ]->clk, hws[IMX6UL_CLK_PLL2_PFD2 ]->clk); -clk_set_parent (hws[IMX6UL_CLK_ENET1_REF_SEL ]->clk, hws[IMX6UL_CLK_ENET_REF ]->clk); -clk_set_parent (hws[IMX6UL_CLK_ENET2_REF_SEL ]->clk, hws[IMX6UL_CLK_ENET2_REF ]->clk); +clk_set_parent (hws[IMX6UL_CLK_ENET1_REF_SEL ]->clk, hws[IMX6UL_CLK_ENET1_REF_125M ]->clk); +clk_set_parent (hws[IMX6UL_CLK_ENET2_REF_SEL ]->clk, hws[IMX6UL_CLK_ENET2_REF_125M ]->clk);imx_register_uart_clocks (); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 310/634 clk: imx: composite-8m: Enable gate clk with mcore_booted
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit 8f32e9dd0916eb3fd4bcf550ed1d04542a65cb9e ]
Bootloader might disable some CCM ROOT Slices. So if mcore_booted set with display CCM ROOT disabled by Bootloader, kernel display BLK CTRL driver imx8m_blk_ctrl_driver_init may hang the system because the BUS clk is disabled.
Add back gate ops, but with disable doing nothing, then the CCM ROOT will be enabled when used.
--- drivers/clk/imx/clk-composite-8m.c | 53 +++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 11 deletions(-)
drivers/clk/imx/clk-composite-8m.c +42 -11
@@ -204,6 +204,34 @@ static const struct clk_ops imx8m_clk_composite_mux_ops = { .determine_rate = imx8m_clk_composite_mux_determine_rate, }; +static int imx8m_clk_composite_gate_enable (struct clk_hw *hw) +{ +struct clk_gate *gate =to_clk_gate (hw); +unsigned long flags; +u32 val; + +spin_lock_irqsave (gate->lock, flags); + + val =readl (gate->reg); + val |=BIT (gate->bit_idx); +writel (val, gate->reg); + +spin_unlock_irqrestore (gate->lock, flags); + +return 0 ; +} + +static void imx8m_clk_composite_gate_disable (struct clk_hw *hw) +{ +/* composite clk requires the disable hook */ +} + +static const struct clk_ops imx8m_clk_composite_gate_ops = { + .enable = imx8m_clk_composite_gate_enable, + .disable = imx8m_clk_composite_gate_disable, + .is_enabled = clk_gate_is_enabled, +}; + struct clk_hw *__imx8m_clk_hw_composite(const char *name, const char * const *parent_names, int num_parents, void __iomem *reg,
@@ -217,6 +245,7 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,struct clk_mux *mux;const struct clk_ops *divider_ops;const struct clk_ops *mux_ops; +const struct clk_ops *gate_ops; mux =kzalloc (sizeof (*mux),GFP_KERNEL );if (!mux)
@@ -257,20 +286,22 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name, div->flags =CLK_DIVIDER_ROUND_CLOSEST ;/* skip registering the gate ops if M4 is enabled */ -if (!mcore_booted) { - gate =kzalloc (sizeof (*gate),GFP_KERNEL ); -if (!gate) - goto free_div; - - gate_hw = &gate->hw; - gate->reg = reg; - gate->bit_idx =PCG_CGC_SHIFT ; - gate->lock = &imx_ccm_lock; - } + gate =kzalloc (sizeof (*gate),GFP_KERNEL ); +if (!gate) + goto free_div; + + gate_hw = &gate->hw; + gate->reg = reg; + gate->bit_idx =PCG_CGC_SHIFT ; + gate->lock = &imx_ccm_lock; +if (!mcore_booted) + gate_ops = &clk_gate_ops; +else + gate_ops = &imx8m_clk_composite_gate_ops; hw =clk_hw_register_composite (NULL , name, parent_names, num_parents, mux_hw, mux_ops, div_hw, - divider_ops, gate_hw, &clk_gate_ops, flags); + divider_ops, gate_hw, gate_ops, flags);if (IS_ERR (hw)) goto free_gate;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 311/634 clk: imx: composite-93: keep root clock on when mcore enabled
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacky Bai <[email protected]>
[ Upstream commit d342df11726bfac9c3a9d2037afa508ac0e9e44e ]
Previously we assumed that the root clock slice is enabled by default when kernel boot up. But the bootloader may disable the clocks before jump into kernel. The gate ops should be registered rather than NULL to make sure the disabled clock can be enabled when kernel boot up. Refine the code to skip disable the clock if mcore booted.
--- drivers/clk/imx/clk-composite-93.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
drivers/clk/imx/clk-composite-93.c +8 -7
@@ -76,6 +76,13 @@ static int imx93_clk_composite_gate_enable(struct clk_hw *hw)static void imx93_clk_composite_gate_disable (struct clk_hw *hw) { +/* +* Skip disable the root clock gate if mcore enabled. +* The root clock may be used by the mcore. +*/ +if (mcore_booted) +return ; +imx93_clk_composite_gate_endisable (hw,0 ); }
@@ -222,7 +229,7 @@ struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *p hw =clk_hw_register_composite (NULL , name, parent_names, num_parents, mux_hw, &clk_mux_ro_ops, div_hw, &clk_divider_ro_ops,NULL ,NULL , flags); - }else if (!mcore_booted) { + }else { gate =kzalloc (sizeof (*gate),GFP_KERNEL );if (!gate) goto fail;
@@ -238,12 +245,6 @@ struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *p &imx93_clk_composite_divider_ops, gate_hw, &imx93_clk_composite_gate_ops, flags | CLK_SET_RATE_NO_REPARENT); - }else { - hw =clk_hw_register_composite (NULL , name, parent_names, num_parents, - mux_hw, &imx93_clk_composite_mux_ops, div_hw, - &imx93_clk_composite_divider_ops,NULL , - &imx93_clk_composite_gate_ops, - flags |CLK_SET_RATE_NO_REPARENT ); }if (IS_ERR (hw))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 312/634 clk: imx: composite-7ulp: Check the PCC present bit
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Li <[email protected]>
[ Upstream commit 4717ccadb51e2630790dddd222830702de17f090 ]
When some module is disabled by fuse, its PCC PR bit is default 0 and PCC is not operational. Any write to this PCC will cause SError.
--- drivers/clk/imx/clk-composite-7ulp.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/clk/imx/clk-composite-7ulp.c +7 -0
@@ -14,6 +14,7 @@#include "../clk-fractional-divider.h" #include "clk.h" +#define PCG_PR_MASK BIT(31)#define PCG_PCS_SHIFT 24#define PCG_PCS_MASK 0x7#define PCG_CGC_SHIFT 30
@@ -78,6 +79,12 @@ static struct clk_hw *imx_ulp_clk_hw_composite(const char *name,struct clk_hw *hw;u32 val; + val =readl (reg); +if (!(val &PCG_PR_MASK )) { +pr_info ("PCC PR is 0 for clk:%s, bypass\n" , name); +return 0 ; + } +if (mux_present) { mux =kzalloc (sizeof (*mux),GFP_KERNEL );if (!mux)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 313/634 clk: imx: fracn-gppll: fix fractional part of PLL getting lost
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengfei Li <[email protected]>
[ Upstream commit 7622f888fca125ae46f695edf918798ebc0506c5 ]
Fractional part of PLL gets lost after re-enabling the PLL. the MFN can NOT be automatically loaded when doing frac PLL enable/disable, So when re-enable PLL, configure mfn explicitly.
--- drivers/clk/imx/clk-fracn-gppll.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/clk/imx/clk-fracn-gppll.c +4 -0
@@ -291,6 +291,10 @@ static int clk_fracn_gppll_prepare(struct clk_hw *hw)if (val &POWERUP_MASK )return 0 ; +if (pll->flags &CLK_FRACN_GPPLL_FRACN ) +writel_relaxed (readl_relaxed (pll->base +PLL_NUMERATOR ), + pll->base +PLL_NUMERATOR ); + val |=CLKMUX_BYPASS ;writel_relaxed (val, pll->base +PLL_CTRL );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 314/634 clk: imx: imx8mp: fix clock tree update of TF-A managed clocks
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhipeng Wang <[email protected]>
[ Upstream commit 3d29036853b9cb07ac49e8261fca82a940be5c41 ]
On the i.MX8M*, the TF-A exposes a SiP (Silicon Provider) service for DDR frequency scaling. The imx8m-ddrc-devfreq driver calls the SiP and then does clk_set_parent on the DDR muxes to synchronize the clock tree.
since commit 936c383673b9 ("clk: imx: fix composite peripheral flags"), these TF-A managed muxes have SET_PARENT_GATE set, which results in imx8m-ddrc-devfreq's clk_set_parent after SiP failing with -EBUSY:
clk_set_parent(dram_apb_src, sys1_pll_40m);(busfreq-imx8mq.c)
commit 926bf91248dd
("clk: imx8m: fix clock tree update of TF-A managed clocks") adds this method and enables 8mm, 8mn and 8mq. i.MX8MP also needs it.
This is safe to do, because updating the Linux clock tree to reflect reality will always be glitch-free.
Another reason to this patch is that powersave image BT music requires dram to be 400MTS, so clk_set_parent(dram_alt_src, sys1_pll_800m); is required. Without this patch, it will not succeed.
--- drivers/clk/imx/clk-imx8mp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/imx/clk-imx8mp.c +2 -2
@@ -551,8 +551,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) hws[IMX8MP_CLK_IPG_ROOT ] =imx_clk_hw_divider2 ("ipg_root" ,"ahb_root" , ccm_base +0x9080 ,0 ,1 ); - hws[IMX8MP_CLK_DRAM_ALT ] =imx8m_clk_hw_composite ("dram_alt" , imx8mp_dram_alt_sels, ccm_base +0xa000 ); - hws[IMX8MP_CLK_DRAM_APB ] =imx8m_clk_hw_composite_critical ("dram_apb" , imx8mp_dram_apb_sels, ccm_base +0xa080 ); + hws[IMX8MP_CLK_DRAM_ALT ] =imx8m_clk_hw_fw_managed_composite ("dram_alt" , imx8mp_dram_alt_sels, ccm_base +0xa000 ); + hws[IMX8MP_CLK_DRAM_APB ] =imx8m_clk_hw_fw_managed_composite_critical ("dram_apb" , imx8mp_dram_apb_sels, ccm_base +0xa080 ); hws[IMX8MP_CLK_VPU_G1 ] =imx8m_clk_hw_composite ("vpu_g1" , imx8mp_vpu_g1_sels, ccm_base +0xa100 ); hws[IMX8MP_CLK_VPU_G2 ] =imx8m_clk_hw_composite ("vpu_g2" , imx8mp_vpu_g2_sels, ccm_base +0xa180 ); hws[IMX8MP_CLK_CAN1 ] =imx8m_clk_hw_composite ("can1" , imx8mp_can1_sels, ccm_base +0xa200 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 315/634 clk: imx: imx8qxp: Register dc0_bypass0_clk before disp clk
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit e61352d5ecdc0da2e7253121c15d9a3e040f78a1 ]
The initialization order of SCU clocks affects the sequence of SCU clock resume. If there are no other effects, the earlier the initialization, the earlier the resume. During SCU clock resume, the clock rate is restored. As SCFW guidelines, configure the parent clock rate before configuring the child rate.
--- drivers/clk/imx/clk-imx8qxp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/imx/clk-imx8qxp.c +2 -2
@@ -206,11 +206,11 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)imx_clk_scu ("usb3_lpm_div" ,IMX_SC_R_USB_2 ,IMX_SC_PM_CLK_MISC );/* Display controller SS */ -imx_clk_scu2 ("dc0_disp0_clk" , dc0_sels,ARRAY_SIZE (dc0_sels),IMX_SC_R_DC_0 ,IMX_SC_PM_CLK_MISC0 ); -imx_clk_scu2 ("dc0_disp1_clk" , dc0_sels,ARRAY_SIZE (dc0_sels),IMX_SC_R_DC_0 ,IMX_SC_PM_CLK_MISC1 );imx_clk_scu ("dc0_pll0_clk" ,IMX_SC_R_DC_0_PLL_0 ,IMX_SC_PM_CLK_PLL );imx_clk_scu ("dc0_pll1_clk" ,IMX_SC_R_DC_0_PLL_1 ,IMX_SC_PM_CLK_PLL );imx_clk_scu ("dc0_bypass0_clk" ,IMX_SC_R_DC_0_VIDEO0 ,IMX_SC_PM_CLK_BYPASS ); +imx_clk_scu2 ("dc0_disp0_clk" , dc0_sels,ARRAY_SIZE (dc0_sels),IMX_SC_R_DC_0 ,IMX_SC_PM_CLK_MISC0 ); +imx_clk_scu2 ("dc0_disp1_clk" , dc0_sels,ARRAY_SIZE (dc0_sels),IMX_SC_R_DC_0 ,IMX_SC_PM_CLK_MISC1 );imx_clk_scu ("dc0_bypass1_clk" ,IMX_SC_R_DC_0_VIDEO1 ,IMX_SC_PM_CLK_BYPASS );imx_clk_scu2 ("dc1_disp0_clk" , dc1_sels,ARRAY_SIZE (dc1_sels),IMX_SC_R_DC_1 ,IMX_SC_PM_CLK_MISC0 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 316/634 clk: imx: imx8qxp: Parent should be initialized earlier than the clock
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit 766c386c16c9899461b83573a06380d364c6e261 ]
The initialization order of SCU clocks affects the sequence of SCU clock resume. If there are no other effects, the earlier the initialization, the earlier the resume. During SCU clock resume, the clock rate is restored. As SCFW guidelines, configure the parent clock rate before configuring the child rate.
--- drivers/clk/imx/clk-imx8qxp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/imx/clk-imx8qxp.c +3 -3
@@ -170,8 +170,8 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)imx_clk_scu ("pwm_clk" ,IMX_SC_R_LCD_0_PWM_0 ,IMX_SC_PM_CLK_PER );imx_clk_scu ("elcdif_pll" ,IMX_SC_R_ELCDIF_PLL ,IMX_SC_PM_CLK_PLL );imx_clk_scu2 ("lcd_clk" , lcd_sels,ARRAY_SIZE (lcd_sels),IMX_SC_R_LCD_0 ,IMX_SC_PM_CLK_PER ); -imx_clk_scu2 ("lcd_pxl_clk" , lcd_pxl_sels,ARRAY_SIZE (lcd_pxl_sels),IMX_SC_R_LCD_0 ,IMX_SC_PM_CLK_MISC0 );imx_clk_scu ("lcd_pxl_bypass_div_clk" ,IMX_SC_R_LCD_0 ,IMX_SC_PM_CLK_BYPASS ); +imx_clk_scu2 ("lcd_pxl_clk" , lcd_pxl_sels,ARRAY_SIZE (lcd_pxl_sels),IMX_SC_R_LCD_0 ,IMX_SC_PM_CLK_MISC0 );/* Audio SS */ imx_clk_scu ("audio_pll0_clk" ,IMX_SC_R_AUDIO_PLL_0 ,IMX_SC_PM_CLK_PLL );
@@ -213,11 +213,11 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)imx_clk_scu2 ("dc0_disp1_clk" , dc0_sels,ARRAY_SIZE (dc0_sels),IMX_SC_R_DC_0 ,IMX_SC_PM_CLK_MISC1 );imx_clk_scu ("dc0_bypass1_clk" ,IMX_SC_R_DC_0_VIDEO1 ,IMX_SC_PM_CLK_BYPASS ); -imx_clk_scu2 ("dc1_disp0_clk" , dc1_sels,ARRAY_SIZE (dc1_sels),IMX_SC_R_DC_1 ,IMX_SC_PM_CLK_MISC0 ); -imx_clk_scu2 ("dc1_disp1_clk" , dc1_sels,ARRAY_SIZE (dc1_sels),IMX_SC_R_DC_1 ,IMX_SC_PM_CLK_MISC1 );imx_clk_scu ("dc1_pll0_clk" ,IMX_SC_R_DC_1_PLL_0 ,IMX_SC_PM_CLK_PLL );imx_clk_scu ("dc1_pll1_clk" ,IMX_SC_R_DC_1_PLL_1 ,IMX_SC_PM_CLK_PLL );imx_clk_scu ("dc1_bypass0_clk" ,IMX_SC_R_DC_1_VIDEO0 ,IMX_SC_PM_CLK_BYPASS ); +imx_clk_scu2 ("dc1_disp0_clk" , dc1_sels,ARRAY_SIZE (dc1_sels),IMX_SC_R_DC_1 ,IMX_SC_PM_CLK_MISC0 ); +imx_clk_scu2 ("dc1_disp1_clk" , dc1_sels,ARRAY_SIZE (dc1_sels),IMX_SC_R_DC_1 ,IMX_SC_PM_CLK_MISC1 );imx_clk_scu ("dc1_bypass1_clk" ,IMX_SC_R_DC_1_VIDEO1 ,IMX_SC_PM_CLK_BYPASS );/* MIPI-LVDS SS */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 317/634 quota: avoid missing put_quota_format when DQUOT_SUSPENDED is passed
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kemeng Shi <[email protected]>
[ Upstream commit d16a5f852025be546b6e4ceef15899db3490f4d7 ]
Avoid missing put_quota_format when DQUOT_SUSPENDED is passed to dquot_load_quota_sb.
--- fs/quota/dquot.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/quota/dquot.c +2 -1
@@ -2408,7 +2408,7 @@ static int vfs_setup_quota_inode(struct inode *inode, int type)int dquot_load_quota_sb (struct super_block *sb,int type,int format_id,unsigned int flags) { -struct quota_format_type *fmt =find_quota_format (format_id); +struct quota_format_type *fmt;struct quota_info *dqopt =sb_dqopt (sb);int error;
@@ -2418,6 +2418,7 @@ int dquot_load_quota_sb(struct super_block *sb, int type, int format_id,if (WARN_ON_ONCE (flags &DQUOT_SUSPENDED ))return -EINVAL ; + fmt =find_quota_format (format_id);if (!fmt)return -ESRCH ; if (!sb->dq_op || !sb->s_qcop ||
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 318/634 remoteproc: imx_rproc: Correct ddr alias for i.MX8M
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit c901f817792822eda9cec23814a4621fa3e66695 ]
The DDR Alias address should be 0x40000000 according to RM, so correct it.
--- drivers/remoteproc/imx_rproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/remoteproc/imx_rproc.c +1 -1
@@ -210,7 +210,7 @@ static const struct imx_rproc_att imx_rproc_att_imx8mq[] = {/* QSPI Code - alias */ { 0x08000000, 0x08000000, 0x08000000, 0 },/* DDR (Code) - alias */ - { 0x10000000, 0x80000000, 0x0FFE0000, 0 }, + { 0x10000000, 0x40000000, 0x0FFE0000, 0 },/* TCML */ { 0x1FFE0000, 0x007E0000, 0x00020000, ATT_OWN | ATT_IOMEM}, /* TCMU */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 319/634 remoteproc: imx_rproc: Initialize workqueue earlier
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit 858e57c1d3dd7b92cc0fa692ba130a0a5d57e49d ]
Initialize workqueue before requesting mailbox channel, otherwise if mailbox interrupt comes before workqueue ready, the imx_rproc_rx_callback will trigger issue.
--- drivers/remoteproc/imx_rproc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/remoteproc/imx_rproc.c +2 -2
@@ -1076,6 +1076,8 @@ static int imx_rproc_probe(struct platform_device *pdev)return -ENOMEM ; } +INIT_WORK (&priv->rproc_work, imx_rproc_vq_work); + ret =imx_rproc_xtr_mbox_init (rproc);if (ret) goto err_put_wkq;
@@ -1094,8 +1096,6 @@ static int imx_rproc_probe(struct platform_device *pdev)if (ret) goto err_put_scu; -INIT_WORK (&priv->rproc_work, imx_rproc_vq_work); -if (rproc->state !=RPROC_DETACHED ) rproc->auto_boot =of_property_read_bool (np,"fsl,auto-boot" );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 320/634 clk: rockchip: Set parent rate for DCLK_VOP clock on RK3228
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Karlman <[email protected]>
[ Upstream commit 1d34b9757523c1ad547bd6d040381f62d74a3189 ]
Similar to DCLK_LCDC on RK3328, the DCLK_VOP on RK3228 is typically parented by the hdmiphy clk and it is expected that the DCLK_VOP and hdmiphy clk rate are kept in sync.
Use CLK_SET_RATE_PARENT and CLK_SET_RATE_NO_REPARENT flags, same as used on RK3328, to make full use of all possible supported display modes.
--- drivers/clk/rockchip/clk-rk3228.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/rockchip/clk-rk3228.c +1 -1
@@ -409,7 +409,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKSEL_CON(29), 0, 3, DFLAGS),DIV (0 ,"sclk_vop_pre" ,"sclk_vop_src" ,0 ,RK2928_CLKSEL_CON (27 ),8 ,8 ,DFLAGS ), -MUX (DCLK_VOP ,"dclk_vop" , mux_dclk_vop_p,0 , +MUX (DCLK_VOP ,"dclk_vop" , mux_dclk_vop_p,CLK_SET_RATE_PARENT |CLK_SET_RATE_NO_REPARENT ,RK2928_CLKSEL_CON (27 ),1 ,1 ,MFLAGS ), FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 321/634 clk: qcom: dispcc-sm8550: fix several supposed typos
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit 7b6a4b907297b28727933493b9e0c95494504634 ]
Fix seveal odd-looking places in SM8550's dispcc driver:
- duplicate entries in disp_cc_parent_map_4 and disp_cc_parent_map_5
- using &disp_cc_mdss_dptx0_link_div_clk_src as a source for disp_cc_mdss_dptx1_usb_router_link_intf_clk
The SM8650 driver has been used as a reference.
--- drivers/clk/qcom/dispcc-sm8550.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/qcom/dispcc-sm8550.c +2 -2
@@ -196,7 +196,7 @@ static const struct clk_parent_data disp_cc_parent_data_3[] = {static const struct parent_map disp_cc_parent_map_4[] = { {P_BI_TCXO ,0 }, {P_DP0_PHY_PLL_LINK_CLK ,1 }, - {P_DP1_PHY_PLL_VCO_DIV_CLK ,2 }, + {P_DP0_PHY_PLL_VCO_DIV_CLK ,2 }, {P_DP3_PHY_PLL_VCO_DIV_CLK ,3 }, {P_DP1_PHY_PLL_VCO_DIV_CLK ,4 }, {P_DP2_PHY_PLL_VCO_DIV_CLK ,6 },
@@ -213,7 +213,7 @@ static const struct clk_parent_data disp_cc_parent_data_4[] = {static const struct parent_map disp_cc_parent_map_5[] = { {P_BI_TCXO ,0 }, - {P_DSI0_PHY_PLL_OUT_BYTECLK ,4 }, + {P_DSI0_PHY_PLL_OUT_BYTECLK ,2 }, {P_DSI1_PHY_PLL_OUT_BYTECLK ,4 }, };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 322/634 clk: qcom: dispcc-sm8550: use rcg2_ops for mdss_dptx1_aux_clk_src
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit cb4c00698f2f27d99a69adcce659370ca286cf2a ]
clk_dp_ops should only be used for DisplayPort pixel clocks. Use clk_rcg2_ops for disp_cc_mdss_dptx1_aux_clk_src.
--- drivers/clk/qcom/dispcc-sm8550.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/qcom/dispcc-sm8550.c +1 -1
@@ -400,7 +400,7 @@ static struct clk_rcg2 disp_cc_mdss_dptx1_aux_clk_src = { .parent_data = disp_cc_parent_data_0, .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_dp_ops, + .ops = &clk_rcg2_ops, }, };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 323/634 clk: qcom: dispcc-sm8650: Update the GDSC flags
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit 7de10ddbdb9d03651cff5fbdc8cf01837c698526 ]
Add missing POLL_CFG_GDSCR to the MDSS GDSC flags.
--- drivers/clk/qcom/dispcc-sm8550.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/qcom/dispcc-sm8550.c +2 -2
@@ -1611,7 +1611,7 @@ static struct gdsc mdss_gdsc = { .name = "mdss_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = HW_CTRL | RETAIN_FF_ENABLE, + .flags = POLL_CFG_GDSCR | HW_CTRL | RETAIN_FF_ENABLE, }; static struct gdsc mdss_int2_gdsc = {
@@ -1620,7 +1620,7 @@ static struct gdsc mdss_int2_gdsc = { .name = "mdss_int2_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = HW_CTRL | RETAIN_FF_ENABLE, + .flags = POLL_CFG_GDSCR | HW_CTRL | RETAIN_FF_ENABLE, }; static struct clk_regmap *disp_cc_sm8550_clocks[] = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 324/634 clk: qcom: dispcc-sm8550: use rcg2_shared_ops for ESC RCGs
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit c8bee3ff6c9220092b646ff929f9c832c1adab6d ]
Follow the recommendations and park disp_cc_mdss_esc[01]_clk_src to the XO instead of disabling the clocks by using the clk_rcg2_shared_ops.
--- drivers/clk/qcom/dispcc-sm8550.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/qcom/dispcc-sm8550.c +2 -2
@@ -562,7 +562,7 @@ static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { .parent_data = disp_cc_parent_data_5, .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, };
@@ -577,7 +577,7 @@ static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = { .parent_data = disp_cc_parent_data_5, .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 325/634 leds: bd2606mvv: Fix device child node usage in bd2606mvv_probe()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <[email protected]>
[ Upstream commit ffbf1fcb421429916a861cfc25dfe0c6387dda75 ]
The current implementation accesses the child fwnode handle outside of fwnode_for_each_available_child_node() without incrementing its refcount. Add the missing call to fwnode_handle_get(child).
The cleanup process where child is accessed is not right either because a single call to fwnode_handle_put() is carried out in case of an error, ignoring unasigned nodes at the point when the error happens. Keep child inside of the first loop, and use the helper pointer that receives references via fwnode_handle_get() to handle the child nodes within the second loop.
Moreover, the iterated nodes are direct children of the device node, and the device_for_each_child_node() macro accounts for child node availability. By restricting child to live within that loop, the scoped version of it can be used to simplify the error handling.
fwnode_for_each_available_child_node() is meant to access the child nodes of an fwnode, and therefore not direct child nodes of the device node.
Use device_for_each_child_node_scoped() to indicate device's direct child nodes.
--- drivers/leds/leds-bd2606mvv.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)
drivers/leds/leds-bd2606mvv.c +10 -13
@@ -69,16 +69,14 @@ static const struct regmap_config bd2606mvv_regmap = {static int bd2606mvv_probe (struct i2c_client *client) { -struct fwnode_handle *np, *child;struct device *dev = &client->dev;struct bd2606mvv_priv *priv;struct fwnode_handle *led_fwnodes[BD2606_MAX_LEDS ] = {0 };int active_pairs[BD2606_MAX_LEDS /2 ] = {0 };int err, reg; -int i; +int i, j; - np =dev_fwnode (dev); -if (!np) +if (!dev_fwnode (dev))return -ENODEV ; priv =devm_kzalloc (dev,sizeof (*priv),GFP_KERNEL );
@@ -94,20 +92,18 @@ static int bd2606mvv_probe(struct i2c_client *client)i2c_set_clientdata (client, priv); -fwnode_for_each_available_child_node (np, child) { +device_for_each_child_node_scoped (dev, child) {struct bd2606mvv_led *led; err =fwnode_property_read_u32 (child,"reg" , ®); -if (err) { -fwnode_handle_put (child); +if (err)return err; - } -if (reg <0 || reg >=BD2606_MAX_LEDS || led_fwnodes[reg]) { -fwnode_handle_put (child); + +if (reg <0 || reg >=BD2606_MAX_LEDS || led_fwnodes[reg])return -EINVAL ; - } + led = &priv->leds[reg]; - led_fwnodes[reg] = child; + led_fwnodes[reg] =fwnode_handle_get (child); active_pairs[reg /2 ]++; led->priv = priv; led->led_no = reg;
@@ -130,7 +126,8 @@ static int bd2606mvv_probe(struct i2c_client *client) &priv->leds[i].ldev, &init_data);if (err <0 ) { -fwnode_handle_put (child); +for (j = i; j <BD2606_MAX_LEDS ; j++) +fwnode_handle_put (led_fwnodes[j]);return dev_err_probe (dev, err,"couldn't register LED %s\n" , priv->leds[i].ldev.name);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 326/634 pinctrl: ti: iodelay: Use scope based of_node_put() cleanups
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit 791a8bb202a85f707c20ef04a471519e35f089dc ]
Use scope based of_node_put() cleanup to simplify code.
Stable-dep-of: a9f2b249adee ("pinctrl: ti: ti-iodelay: Fix some error handling paths")
--- drivers/pinctrl/ti/pinctrl-ti-iodelay.c | 43 +++++++++---------------- 1 file changed, 15 insertions(+), 28 deletions(-)
drivers/pinctrl/ti/pinctrl-ti-iodelay.c +15 -28
@@ -822,53 +822,48 @@ MODULE_DEVICE_TABLE(of, ti_iodelay_of_match);static int ti_iodelay_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev; -struct device_node *np =of_node_get (dev->of_node); + struct device_node *np __free(device_node) = of_node_get(dev->of_node);struct resource *res;struct ti_iodelay_device *iod; -int ret =0 ; +int ret;if (!np) { - ret = -EINVAL ;dev_err (dev,"No OF node\n" ); - goto exit_out; +return -EINVAL ; } iod =devm_kzalloc (dev,sizeof (*iod),GFP_KERNEL ); -if (!iod) { - ret = -ENOMEM ; - goto exit_out; - } +if (!iod) +return -ENOMEM ; + iod->dev = dev; iod->reg_data =device_get_match_data (dev);if (!iod->reg_data) { - ret = -EINVAL ;dev_err (dev,"No DATA match\n" ); - goto exit_out; +return -EINVAL ; }/* So far We can assume there is only 1 bank of registers */ iod->reg_base =devm_platform_get_and_ioremap_resource (pdev,0 , &res); -if (IS_ERR (iod->reg_base)) { - ret =PTR_ERR (iod->reg_base); - goto exit_out; - } +if (IS_ERR (iod->reg_base)) +return PTR_ERR (iod->reg_base); + iod->phys_base = res->start; iod->regmap =devm_regmap_init_mmio (dev, iod->reg_base, iod->reg_data->regmap_config);if (IS_ERR (iod->regmap)) {dev_err (dev,"Regmap MMIO init failed.\n" ); - ret =PTR_ERR (iod->regmap); - goto exit_out; +return PTR_ERR (iod->regmap); } ret =ti_iodelay_pinconf_init_dev (iod);if (ret) - goto exit_out; +return ret; ret =ti_iodelay_alloc_pins (dev, iod, res->start);if (ret) - goto exit_out; +return ret; iod->desc.pctlops = &ti_iodelay_pinctrl_ops;/* no pinmux ops - we are pinconf */
@@ -879,20 +874,12 @@ static int ti_iodelay_probe(struct platform_device *pdev) ret =devm_pinctrl_register_and_init (dev, &iod->desc, iod, &iod->pctl);if (ret) {dev_err (dev,"Failed to register pinctrl\n" ); - goto exit_out; +return ret; }platform_set_drvdata (pdev, iod); - ret =pinctrl_enable (iod->pctl); -if (ret) - goto exit_out; - -return 0 ; - -exit_out: -of_node_put (np); -return ret; +return pinctrl_enable (iod->pctl); }/**
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 327/634 pinctrl: ti: ti-iodelay: Fix some error handling paths
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
[ Upstream commit a9f2b249adeef2b9744a884355fa8f5e581d507f ]
In the probe, if an error occurs after the ti_iodelay_pinconf_init_dev() call, it is likely that ti_iodelay_pinconf_deinit_dev() should be called, as already done in the remove function.
Also in ti_iodelay_pinconf_init_dev(), if an error occurs after the first regmap_update_bits() call, it is also likely that the deinit() function should be called.
The easier way to fix it is to add a devm_add_action_or_reset() at the rigtht place to have ti_iodelay_pinconf_deinit_dev() called when needed.
Doing so, the .remove() function can be removed, and the associated platform_set_drvdata() call in the probe as well.
--- drivers/pinctrl/ti/pinctrl-ti-iodelay.c | 52 ++++++++++--------------- 1 file changed, 21 insertions(+), 31 deletions(-)
drivers/pinctrl/ti/pinctrl-ti-iodelay.c +21 -31
@@ -273,6 +273,22 @@ static int ti_iodelay_pinconf_set(struct ti_iodelay_device *iod,return r; } +/** +* ti_iodelay_pinconf_deinit_dev() - deinit the iodelay device +* @data: IODelay device +* +* Deinitialize the IODelay device (basically just lock the region back up. +*/ +static void ti_iodelay_pinconf_deinit_dev (void *data) +{ +struct ti_iodelay_device *iod = data; +const struct ti_iodelay_reg_data *reg = iod->reg_data; + +/* lock the iodelay region back again */ +regmap_update_bits (iod->regmap, reg->reg_global_lock_offset, + reg->global_lock_mask, reg->global_lock_val); +} +/** * ti_iodelay_pinconf_init_dev() - Initialize IODelay device * @iod: iodelay device
@@ -295,6 +311,11 @@ static int ti_iodelay_pinconf_init_dev(struct ti_iodelay_device *iod)if (r)return r; + r =devm_add_action_or_reset (iod->dev, ti_iodelay_pinconf_deinit_dev, + iod); +if (r) +return r; +/* Read up Recalibration sequence done by bootloader */ r =regmap_read (iod->regmap, reg->reg_refclk_offset, &val);if (r)
@@ -353,21 +374,6 @@ static int ti_iodelay_pinconf_init_dev(struct ti_iodelay_device *iod)return 0 ; } -/** -* ti_iodelay_pinconf_deinit_dev() - deinit the iodelay device -* @iod: IODelay device -* -* Deinitialize the IODelay device (basically just lock the region back up. -*/ -static void ti_iodelay_pinconf_deinit_dev (struct ti_iodelay_device *iod) -{ -const struct ti_iodelay_reg_data *reg = iod->reg_data; - -/* lock the iodelay region back again */ -regmap_update_bits (iod->regmap, reg->reg_global_lock_offset, - reg->global_lock_mask, reg->global_lock_val); -} -/** * ti_iodelay_get_pingroup() - Find the group mapped by a group selector * @iod: iodelay device
@@ -877,27 +883,11 @@ static int ti_iodelay_probe(struct platform_device *pdev)return ret; } -platform_set_drvdata (pdev, iod); -return pinctrl_enable (iod->pctl); } -/** -* ti_iodelay_remove() - standard remove -* @pdev: platform device -*/ -static void ti_iodelay_remove (struct platform_device *pdev) -{ -struct ti_iodelay_device *iod =platform_get_drvdata (pdev); - -ti_iodelay_pinconf_deinit_dev (iod); - -/* Expect other allocations to be freed by devm */ -} -static struct platform_driver ti_iodelay_driver = { .probe = ti_iodelay_probe, - .remove_new = ti_iodelay_remove, .driver = { .name =DRIVER_NAME , .of_match_table = ti_iodelay_of_match,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 328/634 phy: phy-rockchip-samsung-hdptx: Explicitly include pm_runtime.h
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Ciocaltea <[email protected]>
[ Upstream commit 1b369ff94bc36d2e16c8a91c0ea8ebd329555976 ]
Driver makes use of helpers from pm_runtime.h, but relies on the header file being implicitly included.
Explicitly pull the header in to avoid potential build failures in some configurations.
--- drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 1 + 1 file changed, 1 insertion(+)
drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +1 -0
@@ -15,6 +15,7 @@#include <linux/of_platform.h> #include <linux/phy/phy.h> #include <linux/platform_device.h> +#include <linux/pm_runtime.h> #include <linux/rational.h> #include <linux/regmap.h> #include <linux/reset.h>
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 329/634 Input: ilitek_ts_i2c - avoid wrong input subsystem sync
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emanuele Ghidoli <[email protected]>
[ Upstream commit 7d0b18cd5dc7429917812963611d961fd93cb44d ]
For different reasons i2c transaction may fail or report id in the message may be wrong. Avoid closing the frame in this case as it will result in all contacts being dropped, indicating that nothing is touching the screen anymore, while usually it is not the case.
--- drivers/input/touchscreen/ilitek_ts_i2c.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/input/touchscreen/ilitek_ts_i2c.c +5 -6
@@ -160,15 +160,14 @@ static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts) error =ilitek_i2c_write_and_read (ts,NULL ,0 ,0 , buf,64 );if (error) {dev_err (dev,"get touch info failed, err:%d\n" , error); - goto err_sync_frame; +return error; } report_max_point = buf[REPORT_COUNT_ADDRESS ];if (report_max_point > ts->max_tp) {dev_err (dev,"FW report max point:%d > panel info. max:%d\n" , report_max_point, ts->max_tp); - error = -EINVAL ; - goto err_sync_frame; +return -EINVAL ; } count =DIV_ROUND_UP (report_max_point, packet_max_point);
@@ -178,7 +177,7 @@ static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)if (error) {dev_err (dev,"get touch info. failed, cnt:%d, err:%d\n" , count, error); - goto err_sync_frame; +return error; } }
@@ -203,10 +202,10 @@ static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)ilitek_touch_down (ts, id, x, y); } -err_sync_frame:input_mt_sync_frame (input);input_sync (input); -return error; + +return 0 ; }/* APIs of cmds for ILITEK Touch IC */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 330/634 Input: ilitek_ts_i2c - add report id message validation
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emanuele Ghidoli <[email protected]>
[ Upstream commit 208989744a6f01bed86968473312d4e650e600b3 ]
Ensure that the touchscreen response has correct "report id" byte before processing the touch data and discard other messages.
--- drivers/input/touchscreen/ilitek_ts_i2c.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/input/touchscreen/ilitek_ts_i2c.c +7 -0
@@ -37,6 +37,8 @@#define ILITEK_TP_CMD_GET_MCU_VER 0x61#define ILITEK_TP_CMD_GET_IC_MODE 0xC0 +#define ILITEK_TP_I2C_REPORT_ID 0x48 +#define REPORT_COUNT_ADDRESS 61#define ILITEK_SUPPORT_MAX_POINT 40
@@ -163,6 +165,11 @@ static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)return error; } +if (buf[0 ] !=ILITEK_TP_I2C_REPORT_ID ) { +dev_err (dev,"get touch info failed. Wrong id: 0x%02X\n" , buf[0 ]); +return -EINVAL ; + } + report_max_point = buf[REPORT_COUNT_ADDRESS ];if (report_max_point > ts->max_tp) { dev_err(dev, "FW report max point:%d > panel info. max:%d\n",
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 331/634 drivers: media: dvb-frontends/rtl2832: fix an out-of-bounds write error
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junlin Li <[email protected]>
[ Upstream commit 8ae06f360cfaca2b88b98ca89144548b3186aab1 ]
Ensure index in rtl2832_pid_filter does not exceed 31 to prevent out-of-bounds access.
dev->filters is a 32-bit value, so set_bit and clear_bit functions should only operate on indices from 0 to 31. If index is 32, it will attempt to access a non-existent 33rd bit, leading to out-of-bounds access. Change the boundary check from index > 32 to index >= 32 to resolve this issue.
--- drivers/media/dvb-frontends/rtl2832.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/dvb-frontends/rtl2832.c +1 -1
@@ -983,7 +983,7 @@ static int rtl2832_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid, index, pid, onoff, dev->slave_ts);/* skip invalid PIDs (0x2000) */ -if (pid >0x1fff || index >32 ) +if (pid >0x1fff || index >=32 )return 0 ;if (onoff)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 332/634 drivers: media: dvb-frontends/rtl2830: fix an out-of-bounds write error
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junlin Li <[email protected]>
[ Upstream commit 46d7ebfe6a75a454a5fa28604f0ef1491f9d8d14 ]
Ensure index in rtl2830_pid_filter does not exceed 31 to prevent out-of-bounds access.
dev->filters is a 32-bit value, so set_bit and clear_bit functions should only operate on indices from 0 to 31. If index is 32, it will attempt to access a non-existent 33rd bit, leading to out-of-bounds access. Change the boundary check from index > 32 to index >= 32 to resolve this issue.
--- drivers/media/dvb-frontends/rtl2830.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/dvb-frontends/rtl2830.c +1 -1
@@ -609,7 +609,7 @@ static int rtl2830_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid, int on index, pid, onoff);/* skip invalid PIDs (0x2000) */ -if (pid >0x1fff || index >32 ) +if (pid >0x1fff || index >=32 )return 0 ;if (onoff)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 333/634 PCI: Wait for Link before restoring Downstream Buses
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo Järvinen <[email protected]>
[ Upstream commit 3e40aa29d47e231a54640addf6a09c1f64c5b63f ]
__pci_reset_bus() calls pci_bridge_secondary_bus_reset() to perform the reset and also waits for the Secondary Bus to become again accessible. __pci_reset_bus() then calls pci_bus_restore_locked() that restores the PCI devices connected to the bus, and if necessary, recursively restores also the subordinate buses and their devices.
The logic in pci_bus_restore_locked() does not take into account that after restoring a device on one level, there might be another Link Downstream that can only start to come up after restore has been performed for its Downstream Port device. That is, the Link may require additional wait until it becomes accessible.
Similarly, pci_slot_restore_locked() lacks wait.
Amend pci_bus_restore_locked() and pci_slot_restore_locked() to wait for the Secondary Bus before recursively performing the restore of that bus.
--- drivers/pci/pci.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/pci/pci.c +6 -2
@@ -5598,8 +5598,10 @@ static void pci_bus_restore_locked(struct pci_bus *bus)list_for_each_entry (dev, &bus->devices, bus_list) {pci_dev_restore (dev); -if (dev->subordinate) +if (dev->subordinate) { +pci_bridge_wait_for_secondary_bus (dev,"bus reset" );pci_bus_restore_locked (dev->subordinate); + } } }
@@ -5633,8 +5635,10 @@ static void pci_slot_restore_locked(struct pci_slot *slot)if (!dev->slot || dev->slot != slot)continue ;pci_dev_restore (dev); -if (dev->subordinate) +if (dev->subordinate) { +pci_bridge_wait_for_secondary_bus (dev,"slot reset" );pci_bus_restore_locked (dev->subordinate); + } } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 334/634 firewire: core: correct range of block for case of switch statement
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Sakamoto <[email protected]>
[ Upstream commit ebb9d3ca8f7efc1b6a2f1750d1058eda444883d0 ]
A commit d8527cab6c31 ("firewire: cdev: implement new event to notify response subaction with time stamp") adds an additional case, FW_CDEV_EVENT_RESPONSE2, into switch statement in complete_transaction(). However, the range of block is beyond to the case label and reaches neibour default label.
This commit corrects the range of block. Fortunately, it has few impacts in practice since the local variable in the scope under the label is not used in codes under default label.
--- drivers/firewire/core-cdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firewire/core-cdev.c +1 -1
@@ -599,11 +599,11 @@ static void complete_transaction(struct fw_card *card, int rcode, u32 request_tsqueue_event (client, &e->event, rsp,sizeof (*rsp) + rsp->length,NULL ,0 );break ; + }default :WARN_ON (1 );break ; } - }/* Drop the idr's reference */ client_put (client);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 335/634 PCI: keystone: Fix if-statement expression in ks_pcie_quirk()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 6188a1c762eb9bbd444f47696eda77a5eae6207a ]
This code accidentally uses && where || was intended. It potentially results in a NULL dereference.
Thus, fix the if-statement expression to use the correct condition.
--- drivers/pci/controller/dwc/pci-keystone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/controller/dwc/pci-keystone.c +1 -1
@@ -577,7 +577,7 @@ static void ks_pcie_quirk(struct pci_dev *dev)*/ if (pci_match_id (am6_pci_devids, bridge)) { bridge_dev =pci_get_host_bridge_device (dev); -if (!bridge_dev && !bridge_dev->parent) +if (!bridge_dev || !bridge_dev->parent)return ; ks_pcie =dev_get_drvdata (bridge_dev->parent);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 336/634 media: staging: media: starfive: camss: Drop obsolete return value documentation
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
[ Upstream commit 044fcf738a56d915514e2d651333395b3f8daa62 ]
Recently the function stfcamss_remove() was changed to not return a value. Drop the documentation of the return value in the kernel doc.
--- drivers/staging/media/starfive/camss/stf-camss.c | 2 -- 1 file changed, 2 deletions(-)
drivers/staging/media/starfive/camss/stf-camss.c +0 -2
@@ -358,8 +358,6 @@ static int stfcamss_probe(struct platform_device *pdev)/* * stfcamss_remove - Remove STFCAMSS platform device * @pdev: Pointer to STFCAMSS platform device -* -* Always returns 0. */ static void stfcamss_remove (struct platform_device *pdev) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 337/634 clk: qcom: ipq5332: Register gcc_qdss_tsctr_clk_src
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Varadarajan Narayanan <[email protected]>
[ Upstream commit 0e1ac23dfa3f635e486fdeb08206b981cb0a2a6b ]
gcc_qdss_tsctr_clk_src (enabled in the boot loaders and dependent on gpll4_main) was not registered as one of the ipq5332 clocks. Hence clk_disable_unused() disabled 'gpll4_main' assuming there were no consumers for 'gpll4_main' resulting in system freeze or reboots.
--- drivers/clk/qcom/gcc-ipq5332.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/qcom/gcc-ipq5332.c +1 -0
@@ -3388,6 +3388,7 @@ static struct clk_regmap *gcc_ipq5332_clocks[] = { [GCC_QDSS_DAP_DIV_CLK_SRC] = &gcc_qdss_dap_div_clk_src.clkr, [GCC_QDSS_ETR_USB_CLK] = &gcc_qdss_etr_usb_clk.clkr, [GCC_QDSS_EUD_AT_CLK] = &gcc_qdss_eud_at_clk.clkr, + [GCC_QDSS_TSCTR_CLK_SRC] = &gcc_qdss_tsctr_clk_src.clkr, [GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr, [GCC_QPIC_CLK] = &gcc_qpic_clk.clkr, [GCC_QPIC_IO_MACRO_CLK] = &gcc_qpic_io_macro_clk.clkr,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 338/634 clk: qcom: dispcc-sm8250: use special function for Lucid 5LPE PLL
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit 362be5cbaec2a663eb86b7105313368b4a71fc1e ]
According to msm-5.10 the lucid 5lpe PLLs have require slightly different configuration that trion / lucid PLLs, it doesn't set PLL_UPDATE_BYPASS bit. Add corresponding function and use it for the display clock controller on Qualcomm SM8350 platform.
--- drivers/clk/qcom/clk-alpha-pll.c | 52 ++++++++++++++++++++++++++++++++ drivers/clk/qcom/clk-alpha-pll.h | 2 ++ drivers/clk/qcom/dispcc-sm8250.c | 9 ++++-- 3 files changed, 61 insertions(+), 2 deletions(-)
drivers/clk/qcom/clk-alpha-pll.c +52 -0
@@ -1784,6 +1784,58 @@ const struct clk_ops clk_alpha_pll_agera_ops = { };EXPORT_SYMBOL_GPL (clk_alpha_pll_agera_ops); +/** +* clk_lucid_5lpe_pll_configure - configure the lucid 5lpe pll +* +* @pll: clk alpha pll +* @regmap: register map +* @config: configuration to apply for pll +*/ +void clk_lucid_5lpe_pll_configure (struct clk_alpha_pll *pll,struct regmap *regmap, +const struct alpha_pll_config *config) +{ +/* +* If the bootloader left the PLL enabled it's likely that there are +* RCGs that will lock up if we disable the PLL below. +*/ +if (trion_pll_is_enabled (pll, regmap)) { +pr_debug ("Lucid 5LPE PLL is already enabled, skipping configuration\n" ); +return ; + } + +clk_alpha_pll_write_config (regmap,PLL_L_VAL (pll), config->l); +regmap_write (regmap,PLL_CAL_L_VAL (pll),TRION_PLL_CAL_VAL ); +clk_alpha_pll_write_config (regmap,PLL_ALPHA_VAL (pll), config->alpha); +clk_alpha_pll_write_config (regmap,PLL_CONFIG_CTL (pll), + config->config_ctl_val); +clk_alpha_pll_write_config (regmap,PLL_CONFIG_CTL_U (pll), + config->config_ctl_hi_val); +clk_alpha_pll_write_config (regmap,PLL_CONFIG_CTL_U1 (pll), + config->config_ctl_hi1_val); +clk_alpha_pll_write_config (regmap,PLL_USER_CTL (pll), + config->user_ctl_val); +clk_alpha_pll_write_config (regmap,PLL_USER_CTL_U (pll), + config->user_ctl_hi_val); +clk_alpha_pll_write_config (regmap,PLL_USER_CTL_U1 (pll), + config->user_ctl_hi1_val); +clk_alpha_pll_write_config (regmap,PLL_TEST_CTL (pll), + config->test_ctl_val); +clk_alpha_pll_write_config (regmap,PLL_TEST_CTL_U (pll), + config->test_ctl_hi_val); +clk_alpha_pll_write_config (regmap,PLL_TEST_CTL_U1 (pll), + config->test_ctl_hi1_val); + +/* Disable PLL output */ +regmap_update_bits (regmap,PLL_MODE (pll),PLL_OUTCTRL ,0 ); + +/* Set operation mode to OFF */ +regmap_write (regmap,PLL_OPMODE (pll),PLL_STANDBY ); + +/* Place the PLL in STANDBY mode */ +regmap_update_bits (regmap,PLL_MODE (pll),PLL_RESET_N ,PLL_RESET_N ); +} +EXPORT_SYMBOL_GPL (clk_lucid_5lpe_pll_configure); +static int alpha_pll_lucid_5lpe_enable (struct clk_hw *hw) {struct clk_alpha_pll *pll =to_clk_alpha_pll (hw);
drivers/clk/qcom/clk-alpha-pll.h +2 -0
@@ -205,6 +205,8 @@ void clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,void clk_zonda_pll_configure (struct clk_alpha_pll *pll,struct regmap *regmap,const struct alpha_pll_config *config); +void clk_lucid_5lpe_pll_configure (struct clk_alpha_pll *pll,struct regmap *regmap, +const struct alpha_pll_config *config);void clk_lucid_evo_pll_configure (struct clk_alpha_pll *pll,struct regmap *regmap,const struct alpha_pll_config *config); void clk_lucid_ole_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
drivers/clk/qcom/dispcc-sm8250.c +7 -2
@@ -1357,8 +1357,13 @@ static int disp_cc_sm8250_probe(struct platform_device *pdev) disp_cc_sm8250_clocks[DISP_CC_MDSS_EDP_GTC_CLK_SRC ] =NULL ; } -clk_lucid_pll_configure (&disp_cc_pll0, regmap, &disp_cc_pll0_config); -clk_lucid_pll_configure (&disp_cc_pll1, regmap, &disp_cc_pll1_config); +if (of_device_is_compatible (pdev->dev.of_node,"qcom,sm8350-dispcc" )) { +clk_lucid_5lpe_pll_configure (&disp_cc_pll0, regmap, &disp_cc_pll0_config); +clk_lucid_5lpe_pll_configure (&disp_cc_pll1, regmap, &disp_cc_pll1_config); + }else { +clk_lucid_pll_configure (&disp_cc_pll0, regmap, &disp_cc_pll0_config); +clk_lucid_pll_configure (&disp_cc_pll1, regmap, &disp_cc_pll1_config); + }/* Enable clock gating for MDP clocks */ regmap_update_bits (regmap,0x8000 ,0x10 ,0x10 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 339/634 leds: leds-pca995x: Add support for NXP PCA9956B
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pieterjan Camerlynck <[email protected]>
[ Upstream commit 68d6520d2e76998cdea58f6dd8782de5ab5b28af ]
Add support for PCA9956B chip, which belongs to the same family.
This chip features 24 instead of 16 outputs, so add a chipdef struct to deal with the different register layouts.
Stable-dep-of: 82c5ada1f9d0 ("leds: pca995x: Fix device child node usage in pca995x_probe()")
--- drivers/leds/leds-pca995x.c | 59 ++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 20 deletions(-)
drivers/leds/leds-pca995x.c +39 -20
@@ -19,10 +19,6 @@#define PCA995X_MODE1 0x00#define PCA995X_MODE2 0x01#define PCA995X_LEDOUT0 0x02 -#define PCA9955B_PWM0 0x08 -#define PCA9952_PWM0 0x0A -#define PCA9952_IREFALL 0x43 -#define PCA9955B_IREFALL 0x45/* Auto-increment disabled. Normal mode */ #define PCA995X_MODE1_CFG 0x00
@@ -34,17 +30,38 @@#define PCA995X_LDRX_MASK 0x3#define PCA995X_LDRX_BITS 2 -#define PCA995X_MAX_OUTPUTS 16 +#define PCA995X_MAX_OUTPUTS 24#define PCA995X_OUTPUTS_PER_REG 4#define PCA995X_IREFALL_FULL_CFG 0xFF#define PCA995X_IREFALL_HALF_CFG (PCA995X_IREFALL_FULL_CFG / 2) -#define PCA995X_TYPE_NON_B 0 -#define PCA995X_TYPE_B 1 -#define ldev_to_led (c) container_of(c, struct pca995x_led, ldev) +struct pca995x_chipdef { +unsigned int num_leds; +u8 pwm_base; +u8 irefall; +}; + +static const struct pca995x_chipdef pca9952_chipdef = { + .num_leds =16 , + .pwm_base =0x0a , + .irefall =0x43 , +}; + +static const struct pca995x_chipdef pca9955b_chipdef = { + .num_leds =16 , + .pwm_base =0x08 , + .irefall =0x45 , +}; + +static const struct pca995x_chipdef pca9956b_chipdef = { + .num_leds =24 , + .pwm_base =0x0a , + .irefall =0x40 , +}; +struct pca995x_led {unsigned int led_no;struct led_classdev ldev;
@@ -54,7 +71,7 @@ struct pca995x_led {struct pca995x_chip {struct regmap *regmap;struct pca995x_led leds[PCA995X_MAX_OUTPUTS ]; -int btype; +const struct pca995x_chipdef *chipdef; }; static int pca995x_brightness_set(struct led_classdev *led_cdev,
@@ -62,10 +79,11 @@ static int pca995x_brightness_set(struct led_classdev *led_cdev, {struct pca995x_led *led =ldev_to_led (led_cdev);struct pca995x_chip *chip = led->chip; +const struct pca995x_chipdef *chipdef = chip->chipdef;u8 ledout_addr, pwmout_addr;int shift, ret; - pwmout_addr = (chip->btype ?PCA9955B_PWM0 :PCA9952_PWM0 ) + led->led_no; + pwmout_addr = chipdef->pwm_base + led->led_no; ledout_addr =PCA995X_LEDOUT0 + (led->led_no /PCA995X_OUTPUTS_PER_REG ); shift =PCA995X_LDRX_BITS * (led->led_no %PCA995X_OUTPUTS_PER_REG );
@@ -104,11 +122,12 @@ static int pca995x_probe(struct i2c_client *client)struct fwnode_handle *led_fwnodes[PCA995X_MAX_OUTPUTS ] = {0 };struct fwnode_handle *np, *child;struct device *dev = &client->dev; +const struct pca995x_chipdef *chipdef;struct pca995x_chip *chip;struct pca995x_led *led; -int i, btype, reg, ret; +int i, reg, ret; - btype = (unsigned long )device_get_match_data (&client->dev); + chipdef =device_get_match_data (&client->dev); np =dev_fwnode (dev);if (!np)
@@ -118,7 +137,7 @@ static int pca995x_probe(struct i2c_client *client)if (!chip)return -ENOMEM ; - chip->btype = btype; + chip->chipdef = chipdef; chip->regmap =devm_regmap_init_i2c (client, &pca995x_regmap);if (IS_ERR (chip->regmap))return PTR_ERR (chip->regmap);
@@ -170,21 +189,21 @@ static int pca995x_probe(struct i2c_client *client)return ret;/* IREF Output current value for all LEDn outputs */ -return regmap_write (chip->regmap, - btype ?PCA9955B_IREFALL :PCA9952_IREFALL , -PCA995X_IREFALL_HALF_CFG ); +return regmap_write (chip->regmap, chipdef->irefall,PCA995X_IREFALL_HALF_CFG ); }static const struct i2c_device_id pca995x_id[] = { - {"pca9952" , .driver_data = (kernel_ulong_t )PCA995X_TYPE_NON_B }, - {"pca9955b" , .driver_data = (kernel_ulong_t )PCA995X_TYPE_B }, + {"pca9952" , .driver_data = (kernel_ulong_t)&pca9952_chipdef }, + {"pca9955b" , .driver_data = (kernel_ulong_t)&pca9955b_chipdef }, + {"pca9956b" , .driver_data = (kernel_ulong_t)&pca9956b_chipdef }, {} };MODULE_DEVICE_TABLE (i2c, pca995x_id);static const struct of_device_id pca995x_of_match[] = { - { .compatible ="nxp,pca9952" , .data = (void *)PCA995X_TYPE_NON_B }, - { .compatible ="nxp,pca9955b" , .data = (void *)PCA995X_TYPE_B }, + { .compatible ="nxp,pca9952" , .data = &pca9952_chipdef }, + { .compatible ="nxp,pca9955b" , . data = &pca9955b_chipdef }, + { .compatible ="nxp,pca9956b" , .data = &pca9956b_chipdef }, {}, };MODULE_DEVICE_TABLE (of, pca995x_of_match);
Signature · 1 line
2.43.0
Re: [PATCH 6.10 339/634] leds: leds-pca995x: Add support for NXP PCA9956B
Quoted 4 lines · Greg Kroah-Hartman
6.10-stable review patch. If anyone has any objections, please let me know.
------------------
Quoted 8 lines
From: Pieterjan Camerlynck <[email protected]>
[ Upstream commit
68d6520d2e76998cdea58f6dd8782de5ab5b28af]Add support for PCA9956B chip, which belongs to the same family.
This chip features 24 instead of 16 outputs, so add a chipdef struct to deal with the different register layouts.
This seems like a feature patch, not a fix and not a stable material, right ?
Greg Kroah-Hartman
maintainerPATCH 340/634 leds: pca995x: Use device_for_each_child_node() to access device child nodes
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <[email protected]>
[ Upstream commit 6eefd65ba6ae29ab801f6461e59c10f93dd496f8 ]
The iterated nodes are direct children of the device node, and the device_for_each_child_node() macro accounts for child node availability.
fwnode_for_each_available_child_node() is meant to access the child nodes of an fwnode, and therefore not direct child nodes of the device node.
Use device_for_each_child_node() to indicate device's direct child nodes.
Stable-dep-of: 82c5ada1f9d0 ("leds: pca995x: Fix device child node usage in pca995x_probe()")
--- drivers/leds/leds-pca995x.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)
drivers/leds/leds-pca995x.c +5 -10
@@ -120,7 +120,7 @@ static const struct regmap_config pca995x_regmap = {static int pca995x_probe (struct i2c_client *client) {struct fwnode_handle *led_fwnodes[PCA995X_MAX_OUTPUTS ] = {0 }; -struct fwnode_handle *np, *child; +struct fwnode_handle *child;struct device *dev = &client->dev;const struct pca995x_chipdef *chipdef;struct pca995x_chip *chip;
@@ -129,8 +129,7 @@ static int pca995x_probe(struct i2c_client *client) chipdef =device_get_match_data (&client->dev); - np =dev_fwnode (dev); -if (!np) +if (!dev_fwnode (dev))return -ENODEV ; chip =devm_kzalloc (dev,sizeof (*chip),GFP_KERNEL );
@@ -144,17 +143,13 @@ static int pca995x_probe(struct i2c_client *client)i2c_set_clientdata (client, chip); -fwnode_for_each_available_child_node (np, child) { +device_for_each_child_node (dev, child) { ret =fwnode_property_read_u32 (child,"reg" , ®); -if (ret) { -fwnode_handle_put (child); +if (ret)return ret; - } -if (reg <0 || reg >=PCA995X_MAX_OUTPUTS || led_fwnodes[reg]) { -fwnode_handle_put (child); +if (reg <0 || reg >=PCA995X_MAX_OUTPUTS || led_fwnodes[reg])return -EINVAL ; - } led = &chip->leds[reg]; led_fwnodes[reg] = child;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 341/634 leds: pca995x: Fix device child node usage in pca995x_probe()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <[email protected]>
[ Upstream commit 82c5ada1f9d05902a4ccb926c7ce34e2fe699283 ]
The current implementation accesses the child fwnode handle outside of device_for_each_child_node() without incrementing its refcount.
Add the missing call to fwnode_handle_get(child).
The cleanup process where child is accessed is not right either because a single call to fwnode_handle_put() is carried out in case of an error, ignoring unasigned nodes at the point when the error happens.
Keep child inside of the first loop, and use the helper pointer that receives references via fwnode_handle_get() to handle the child nodes within the second loop. Keeping child inside the first node has also the advantage that the scoped version of the loop can be used.
--- drivers/leds/leds-pca995x.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/leds/leds-pca995x.c +5 -5
@@ -120,12 +120,11 @@ static const struct regmap_config pca995x_regmap = {static int pca995x_probe (struct i2c_client *client) {struct fwnode_handle *led_fwnodes[PCA995X_MAX_OUTPUTS ] = {0 }; -struct fwnode_handle *child;struct device *dev = &client->dev;const struct pca995x_chipdef *chipdef;struct pca995x_chip *chip;struct pca995x_led *led; -int i, reg, ret; +int i, j, reg, ret; chipdef =device_get_match_data (&client->dev);
@@ -143,7 +142,7 @@ static int pca995x_probe(struct i2c_client *client)i2c_set_clientdata (client, chip); -device_for_each_child_node (dev, child) { +device_for_each_child_node_scoped (dev, child) { ret =fwnode_property_read_u32 (child,"reg" , ®);if (ret)return ret;
@@ -152,7 +151,7 @@ static int pca995x_probe(struct i2c_client *client)return -EINVAL ; led = &chip->leds[reg]; - led_fwnodes[reg] = child; + led_fwnodes[reg] =fwnode_handle_get (child); led->chip = chip; led->led_no = reg; led->ldev.brightness_set_blocking = pca995x_brightness_set;
@@ -171,7 +170,8 @@ static int pca995x_probe(struct i2c_client *client) &chip->leds[i].ldev, &init_data);if (ret <0 ) { -fwnode_handle_put (child); +for (j = i; j <PCA995X_MAX_OUTPUTS ; j++) +fwnode_handle_put (led_fwnodes[j]);return dev_err_probe (dev, ret,"Could not register LED %s\n" , chip->leds[i].ldev.name);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 342/634 x86/PCI: Check pcie_find_root_port() return for NULL
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Samasth Norway Ananda <[email protected]>
[ Upstream commit dbc3171194403d0d40e4bdeae666f6e76e428b53 ]
If pcie_find_root_port() is unable to locate a Root Port, it will return NULL. Check the pointer for NULL before dereferencing it.
This particular case is in a quirk for devices that are always below a Root Port, so this won't avoid a problem and doesn't need to be backported, but check as a matter of style and to prevent copy/paste mistakes.
--- arch/x86/pci/fixup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/pci/fixup.c +2 -2
@@ -980,7 +980,7 @@ static void amd_rp_pme_suspend(struct pci_dev *dev)return ; rp =pcie_find_root_port (dev); -if (!rp->pm_cap) +if (!rp || !rp->pm_cap)return ; rp->pme_support &= ~((PCI_PM_CAP_PME_D3hot|PCI_PM_CAP_PME_D3cold) >>
@@ -994,7 +994,7 @@ static void amd_rp_pme_resume(struct pci_dev *dev)u16 pmc; rp =pcie_find_root_port (dev); -if (!rp->pm_cap) +if (!rp || !rp->pm_cap)return ;pci_read_config_word (rp, rp->pm_cap +PCI_PM_PMC , &pmc);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 343/634 nvdimm: Fix devs leaks in scan_labels()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Zhijian <[email protected]>
[ Upstream commit 62c2aa6b1f565d2fc1ec11a6e9e8336ce37a6426 ]
scan_labels() leaks memory when label scanning fails and it falls back to just creating a default "seed" namespace for userspace to configure. Root can force the kernel to leak memory.
Allocate the minimum resources unconditionally and release them when unneeded to avoid the memory leak.
A kmemleak reports:
unreferenced object 0xffff88800dda1980 (size 16):
comm "kworker/u10:5", pid 69, jiffies 4294671781 hex dump (first 16 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace (crc 0):
[<00000000c5dea560>] __kmalloc+0x32c/0x470
[<000000009ed43c83>] nd_region_register_namespaces+0x6fb/0x1120 [libnvdimm]
[<000000000e07a65c>] nd_region_probe+0xfe/0x210 [libnvdimm]
[<000000007b79ce5f>] nvdimm_bus_probe+0x7a/0x1e0 [libnvdimm]
[<00000000a5f3da2e>] really_probe+0xc6/0x390
[<00000000129e2a69>] __driver_probe_device+0x78/0x150
[<000000002dfed28b>] driver_probe_device+0x1e/0x90
[<00000000e7048de2>] __device_attach_driver+0x85/0x110
[<0000000032dca295>] bus_for_each_drv+0x85/0xe0
[<00000000391c5a7d>] __device_attach+0xbe/0x1e0
[<0000000026dabec0>] bus_probe_device+0x94/0xb0
[<00000000c590d936>] device_add+0x656/0x870
[<000000003d69bfaa>] nd_async_device_register+0xe/0x50 [libnvdimm]
[<000000003f4c52a4>] async_run_entry_fn+0x2e/0x110
[<00000000e201f4b0>] process_one_work+0x1ee/0x600
[<000000006d90d5a9>] worker_thread+0x183/0x350--- drivers/nvdimm/namespace_devs.c | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-)
drivers/nvdimm/namespace_devs.c +17 -17
@@ -1937,12 +1937,16 @@ static int cmp_dpa(const void *a, const void *b)static struct device **scan_labels (struct nd_region *nd_region) {int i, count =0 ; -struct device *dev, **devs =NULL ; +struct device *dev, **devs;struct nd_label_ent *label_ent, *e;struct nd_mapping *nd_mapping = &nd_region->mapping[0 ];struct nvdimm_drvdata *ndd =to_ndd (nd_mapping);resource_size_t map_end = nd_mapping->start + nd_mapping->size -1 ; + devs =kcalloc (2 ,sizeof (dev),GFP_KERNEL ); +if (!devs) +return NULL ; +/* "safe" because create_namespace_pmem() might list_move() label_ent */ list_for_each_entry_safe (label_ent, e, &nd_mapping->labels, list) {struct nd_namespace_label *nd_label = label_ent->label;
@@ -1961,12 +1965,14 @@ static struct device **scan_labels(struct nd_region *nd_region) goto err;if (i < count)continue ; - __devs =kcalloc (count +2 ,sizeof (dev),GFP_KERNEL ); -if (!__devs) - goto err; -memcpy (__devs, devs,sizeof (dev) * count); -kfree (devs); - devs = __devs; +if (count) { + __devs =kcalloc (count +2 ,sizeof (dev),GFP_KERNEL ); +if (!__devs) + goto err; +memcpy (__devs, devs,sizeof (dev) * count); +kfree (devs); + devs = __devs; + } dev =create_namespace_pmem (nd_region, nd_mapping, nd_label);if (IS_ERR (dev)) {
@@ -1993,11 +1999,6 @@ static struct device **scan_labels(struct nd_region *nd_region)/* Publish a zero-sized namespace for userspace to configure. */ nd_mapping_free_labels (nd_mapping); - - devs =kcalloc (2 ,sizeof (dev),GFP_KERNEL ); -if (!devs) - goto err; - nspm =kzalloc (sizeof (*nspm),GFP_KERNEL );if (!nspm) goto err;
@@ -2036,11 +2037,10 @@ static struct device **scan_labels(struct nd_region *nd_region)return devs; err: -if (devs) { -for (i =0 ; devs[i]; i++) -namespace_pmem_release (devs[i]); -kfree (devs); - } +for (i =0 ; devs[i]; i++) +namespace_pmem_release (devs[i]); +kfree (devs); +return NULL ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 344/634 PCI: xilinx-nwl: Fix register misspelling
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Anderson <[email protected]>
[ Upstream commit a437027ae1730b8dc379c75fa0dd7d3036917400 ]
MSIC -> MISC
--- drivers/pci/controller/pcie-xilinx-nwl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/pci/controller/pcie-xilinx-nwl.c +6 -6
@@ -80,8 +80,8 @@#define MSGF_MISC_SR_NON_FATAL_DEV BIT(22)#define MSGF_MISC_SR_FATAL_DEV BIT(23)#define MSGF_MISC_SR_LINK_DOWN BIT(24) -#define MSGF_MSIC_SR_LINK_AUTO_BWIDTH BIT(25) -#define MSGF_MSIC_SR_LINK_BWIDTH BIT(26) +#define MSGF_MISC_SR_LINK_AUTO_BWIDTH BIT(25) +#define MSGF_MISC_SR_LINK_BWIDTH BIT(26)#define MSGF_MISC_SR_MASKALL (MSGF_MISC_SR_RXMSG_AVAIL | \ MSGF_MISC_SR_RXMSG_OVER | \
@@ -96,8 +96,8 @@ MSGF_MISC_SR_NON_FATAL_DEV | \ MSGF_MISC_SR_FATAL_DEV | \ MSGF_MISC_SR_LINK_DOWN | \ - MSGF_MSIC_SR_LINK_AUTO_BWIDTH | \ - MSGF_MSIC_SR_LINK_BWIDTH) + MSGF_MISC_SR_LINK_AUTO_BWIDTH | \ + MSGF_MISC_SR_LINK_BWIDTH)/* Legacy interrupt status mask bits */ #define MSGF_LEG_SR_INTA BIT(0)
@@ -299,10 +299,10 @@ static irqreturn_t nwl_pcie_misc_handler(int irq, void *data)if (misc_stat &MSGF_MISC_SR_FATAL_DEV )dev_err (dev,"Fatal Error Detected\n" ); -if (misc_stat &MSGF_MSIC_SR_LINK_AUTO_BWIDTH ) +if (misc_stat &MSGF_MISC_SR_LINK_AUTO_BWIDTH )dev_info (dev,"Link Autonomous Bandwidth Management Status bit set\n" ); -if (misc_stat &MSGF_MSIC_SR_LINK_BWIDTH ) +if (misc_stat &MSGF_MISC_SR_LINK_BWIDTH )dev_info (dev,"Link Bandwidth Management Status bit set\n" );/* Clear misc interrupt status */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 345/634 PCI: xilinx-nwl: Clean up clock on probe failure/removal
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Anderson <[email protected]>
[ Upstream commit cfd67903977b13f63340a4eb5a1cc890994f2c62 ]
Make sure we turn off the clock on probe failure and device removal.
--- drivers/pci/controller/pcie-xilinx-nwl.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
drivers/pci/controller/pcie-xilinx-nwl.c +19 -4
@@ -779,6 +779,7 @@ static int nwl_pcie_probe(struct platform_device *pdev)return -ENODEV ; pcie =pci_host_bridge_priv (bridge); +platform_set_drvdata (pdev, pcie); pcie->dev = dev;
@@ -801,13 +802,13 @@ static int nwl_pcie_probe(struct platform_device *pdev) err =nwl_pcie_bridge_init (pcie);if (err) {dev_err (dev,"HW Initialization failed\n" ); -return err; + goto err_clk; } err =nwl_pcie_init_irq_domain (pcie);if (err) {dev_err (dev,"Failed creating IRQ Domain\n" ); -return err; + goto err_clk; } bridge->sysdata = pcie;
@@ -817,11 +818,24 @@ static int nwl_pcie_probe(struct platform_device *pdev) err =nwl_pcie_enable_msi (pcie);if (err <0 ) {dev_err (dev,"failed to enable MSI support: %d\n" , err); -return err; + goto err_clk; } } -return pci_host_probe (bridge); + err =pci_host_probe (bridge); +if (!err) +return 0 ; + +err_clk: +clk_disable_unprepare (pcie->clk); +return err; +} + +static void nwl_pcie_remove (struct platform_device *pdev) +{ +struct nwl_pcie *pcie =platform_get_drvdata (pdev); + +clk_disable_unprepare (pcie->clk); }static struct platform_driver nwl_pcie_driver = {
@@ -831,5 +845,6 @@ static struct platform_driver nwl_pcie_driver = { .of_match_table = nwl_pcie_of_match, }, .probe = nwl_pcie_probe, + .remove_new = nwl_pcie_remove, };builtin_platform_driver (nwl_pcie_driver);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 346/634 leds: gpio: Set num_leds after allocation
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
[ Upstream commit 045391a02bd971d431c83ad03f7cc51b6e2fe331 ]
With the new __counted_by annotation, the "num_leds" variable needs to valid for accesses to the "leds" array. This requirement is not met in gpio_leds_create(), since "num_leds" starts at "0", so "leds" index "0" will not be considered valid (num_leds would need to be "1" to access index "0").
Fix this by setting the allocation size after allocation, and then update the final count based on how many were actually added to the array.
--- drivers/leds/leds-gpio.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/leds/leds-gpio.c +6 -3
@@ -150,7 +150,7 @@ static struct gpio_leds_priv *gpio_leds_create(struct device *dev) {struct fwnode_handle *child;struct gpio_leds_priv *priv; -int count, ret; +int count, used, ret; count =device_get_child_node_count (dev);if (!count)
@@ -159,9 +159,11 @@ static struct gpio_leds_priv *gpio_leds_create(struct device *dev) priv =devm_kzalloc (dev,struct_size (priv, leds, count),GFP_KERNEL );if (!priv)return ERR_PTR (-ENOMEM ); + priv->num_leds = count; + used =0 ;device_for_each_child_node (dev, child) { -struct gpio_led_data *led_dat = &priv->leds[priv->num_leds]; +struct gpio_led_data *led_dat = &priv->leds[used];struct gpio_led led = {};/*
@@ -197,8 +199,9 @@ static struct gpio_leds_priv *gpio_leds_create(struct device *dev)/* Set gpiod label to match the corresponding LED name. */ gpiod_set_consumer_name (led_dat->gpiod, led_dat->cdev.dev->kobj.name); - priv->num_leds++; + used++; } + priv->num_leds = used;return priv; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 347/634 media: platform: rzg2l-cru: rzg2l-csi2: Add missing MODULE_DEVICE_TABLE
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Biju Das <[email protected]>
[ Upstream commit 07668fb0f867388bfdac0b60dbf51a4ad789f8e7 ]
The rzg2l-csi2 driver can be compiled as a module, but lacks MODULE_DEVICE_TABLE() and will therefore not be loaded automatically. Fix this.
--- drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c +1 -0
@@ -865,6 +865,7 @@ static const struct of_device_id rzg2l_csi2_of_table[] = { { .compatible = "renesas,rzg2l-csi2", }, {/* sentinel */ } }; +MODULE_DEVICE_TABLE (of, rzg2l_csi2_of_table);static struct platform_driver rzg2l_csi2_pdrv = { .remove_new = rzg2l_csi2_remove,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 348/634 RDMA/iwcm: Fix WARNING:at_kernel/workqueue.c:#check_flush_dependency
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhu Yanjun <[email protected]>
[ Upstream commit 86dfdd8288907f03c18b7fb462e0e232c4f98d89 ]
In the commit aee2424246f9 ("RDMA/iwcm: Fix a use-after-free related to destroying CM IDs"), the function flush_workqueue is invoked to flush the work queue iwcm_wq.
But at that time, the work queue iwcm_wq was created via the function alloc_ordered_workqueue without the flag WQ_MEM_RECLAIM.
Because the current process is trying to flush the whole iwcm_wq, if iwcm_wq doesn't have the flag WQ_MEM_RECLAIM, verify that the current process is not reclaiming memory or running on a workqueue which doesn't have the flag WQ_MEM_RECLAIM as that can break forward-progress guarantee leading to a deadlock.
The call trace is as below:
[ 125.350876][ T1430] Call Trace: [ 125.356281][ T1430] <TASK> [ 125.361285][ T1430] ? __warn (kernel/panic.c:693) [ 125.367640][ T1430] ? check_flush_dependency (kernel/workqueue.c:3706 (discriminator 9)) [ 125.375689][ T1430] ? report_bug (lib/bug.c:180 lib/bug.c:219) [ 125.382505][ T1430] ? handle_bug (arch/x86/kernel/traps.c:239) [ 125.388987][ T1430] ? exc_invalid_op (arch/x86/kernel/traps.c:260 (discriminator 1)) [ 125.395831][ T1430] ? asm_exc_invalid_op (arch/x86/include/asm/idtentry.h:621) [ 125.403125][ T1430] ? check_flush_dependency (kernel/workqueue.c:3706 (discriminator 9)) [ 125.410984][ T1430] ? check_flush_dependency (kernel/workqueue.c:3706 (discriminator 9)) [ 125.418764][ T1430] __flush_workqueue (kernel/workqueue.c:3970) [ 125.426021][ T1430] ? __pfx___might_resched (kernel/sched/core.c:10151) [ 125.433431][ T1430] ? destroy_cm_id (drivers/infiniband/core/iwcm.c:375) iw_cm [ 125.441209][ T1430] ? __pfx___flush_workqueue (kernel/workqueue.c:3910) [ 125.473900][ T1430] ? _raw_spin_lock_irqsave (arch/x86/include/asm/atomic.h:107 include/linux/atomic/atomic-arch-fallback.h:2170 include/linux/atomic/atomic-instrumented.h:1302 include/asm-generic/qspinlock.h:111 include/linux/spinlock.h:187 include/linux/spinlock_api_smp.h:111 kernel/locking/spinlock.c:162) [ 125.473909][ T1430] ? __pfx__raw_spin_lock_irqsave (kernel/locking/spinlock.c:161) [ 125.482537][ T1430] _destroy_id (drivers/infiniband/core/cma.c:2044) rdma_cm [ 125.495072][ T1430] nvme_rdma_free_queue (drivers/nvme/host/rdma.c:656 drivers/nvme/host/rdma.c:650) nvme_rdma [ 125.505827][ T1430] nvme_rdma_reset_ctrl_work (drivers/nvme/host/rdma.c:2180) nvme_rdma [ 125.505831][ T1430] process_one_work (kernel/workqueue.c:3231) [ 125.515122][ T1430] worker_thread (kernel/workqueue.c:3306 kernel/workqueue.c:3393) [ 125.515127][ T1430] ? __pfx_worker_thread (kernel/workqueue.c:3339) [ 125.531837][ T1430] kthread (kernel/kthread.c:389) [ 125.539864][ T1430] ? __pfx_kthread (kernel/kthread.c:342) [ 125.550628][ T1430] ret_from_fork (arch/x86/kernel/process.c:147) [ 125.558840][ T1430] ? __pfx_kthread (kernel/kthread.c:342) [ 125.558844][ T1430] ret_from_fork_asm (arch/x86/entry/entry_64.S:257) [ 125.566487][ T1430] </TASK> [ 125.566488][ T1430] ---[ end trace 0000000000000000 ]---
--- drivers/infiniband/core/iwcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/core/iwcm.c +1 -1
@@ -1190,7 +1190,7 @@ static int __init iw_cm_init(void)if (ret)return ret; - iwcm_wq =alloc_ordered_workqueue ("iw_cm_wq" ,0 ); + iwcm_wq =alloc_ordered_workqueue ("iw_cm_wq" ,WQ_MEM_RECLAIM );if (!iwcm_wq) goto err_alloc;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 349/634 pinctrl: single: fix missing error code in pcs_probe()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Yingliang <[email protected]>
[ Upstream commit cacd8cf79d7823b07619865e994a7916fcc8ae91 ]
If pinctrl_enable() fails in pcs_probe(), it should return the error code.
--- drivers/pinctrl/pinctrl-single.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/pinctrl/pinctrl-single.c +2 -1
@@ -1913,7 +1913,8 @@ static int pcs_probe(struct platform_device *pdev)dev_info (pcs->dev,"%i pins, size %u\n" , pcs->desc.npins, pcs->size); -if (pinctrl_enable (pcs->pctl)) + ret =pinctrl_enable (pcs->pctl); +if (ret) goto free;return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 350/634 clk: at91: sama7g5: Allocate only the needed amount of memory for PLLs
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudiu Beznea <[email protected]>
[ Upstream commit 2d6e9ee7cb3e79b1713783c633b13af9aeffc90c ]
The maximum number of PLL components on SAMA7G5 is 3 (one fractional part and 2 dividers). Allocate the needed amount of memory for sama7g5_plls 2d array. Previous code used to allocate 7 array entries for each PLL. While at it, replace 3 with PLL_COMPID_MAX in the loop which parses the sama7g5_plls 2d array.
--- drivers/clk/at91/sama7g5.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/clk/at91/sama7g5.c +3 -2
@@ -66,6 +66,7 @@ enum pll_component_id {PLL_COMPID_FRAC ,PLL_COMPID_DIV0 ,PLL_COMPID_DIV1 , + PLL_COMPID_MAX, };/*
@@ -165,7 +166,7 @@ static struct sama7g5_pll {u8 t;u8 eid;u8 safe_div; -} sama7g5_plls[][PLL_ID_MAX] = { +} sama7g5_plls[][PLL_COMPID_MAX] = { [PLL_ID_CPU] = { [PLL_COMPID_FRAC] = { .n = "cpupll_fracck",
@@ -1038,7 +1039,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) sama7g5_pmc->chws[PMC_MAIN ] = hw;for (i =0 ; i <PLL_ID_MAX ; i++) { -for (j =0 ; j <3 ; j++) { +for (j =0 ; j <PLL_COMPID_MAX ; j++) {struct clk_hw *parent_hw;if (!sama7g5_plls[i][j].n)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 351/634 iommufd/selftest: Fix buffer read overrrun in the dirty test
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit 79ea4a496ab5c970a3a793d863ed8893b1af107c ]
test_bit() is used to read the memory storing the bitmap, however test_bit() always uses a unsigned long 8 byte access.
If the bitmap is not an aligned size of 64 bits this will now trigger a KASAN warning reading past the end of the buffer.
Properly round the buffer allocation to an unsigned long size. Continue to copy_from_user() using a byte granularity.
--- drivers/iommu/iommufd/selftest.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/iommu/iommufd/selftest.c +4 -5
@@ -1313,7 +1313,7 @@ static int iommufd_test_dirty(struct iommufd_ucmd *ucmd, unsigned int mockpt_id, unsigned long page_size, void __user *uptr, u32 flags) { - unsigned long bitmap_size, i, max; + unsigned long i, max;struct iommu_test_cmd *cmd = ucmd->cmd;struct iommufd_hw_pagetable *hwpt;struct mock_iommu_domain *mock;
@@ -1334,15 +1334,14 @@ static int iommufd_test_dirty(struct iommufd_ucmd *ucmd, unsigned int mockpt_id, } max = length / page_size; - bitmap_size =DIV_ROUND_UP (max,BITS_PER_BYTE ); - - tmp =kvzalloc (bitmap_size,GFP_KERNEL_ACCOUNT ); + tmp =kvzalloc (DIV_ROUND_UP (max,BITS_PER_LONG ) *sizeof (unsigned long ), +GFP_KERNEL_ACCOUNT );if (!tmp) { rc = -ENOMEM ; goto out_put; } -if (copy_from_user (tmp, uptr, bitmap_size)) { +if (copy_from_user (tmp, uptr,DIV_ROUND_UP (max,BITS_PER_BYTE ))) { rc = -EFAULT ; goto out_free; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 352/634 media: mediatek: vcodec: Fix H264 multi stateless decoder smatch warning
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yunfei Dong <[email protected]>
[ Upstream commit 9be85491619f1953b8a29590ca630be571941ffa ]
Fix a smatch static checker warning on vdec_h264_req_multi_if.c. Which leads to a kernel crash when fb is NULL.
--- .../vcodec/decoder/vdec/vdec_h264_req_multi_if.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c +7 -2
@@ -724,11 +724,16 @@ static int vdec_h264_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bsreturn vpu_dec_reset (vpu); fb = inst->ctx->dev->vdec_pdata->get_cap_buffer (inst->ctx); +if (!fb) { +mtk_vdec_err (inst->ctx,"fb buffer is NULL" ); +return -ENOMEM ; + } + src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer); dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer); - y_fb_dma = fb ? (u64 )fb->base_y.dma_addr :0 ; - c_fb_dma = fb ? (u64 )fb->base_c.dma_addr :0 ; + y_fb_dma = fb->base_y.dma_addr; + c_fb_dma = fb->base_c.dma_addr;mtk_vdec_debug (inst->ctx,"[h264-dec] [%d] y_dma=%llx c_dma=%llx" , inst->ctx->decoded_frame_cnt, y_fb_dma, c_fb_dma);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 353/634 media: mediatek: vcodec: Fix VP8 stateless decoder smatch warning
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yunfei Dong <[email protected]>
[ Upstream commit b113bc7c0e83b32f4dd2d291a2b6c4803e0a2c44 ]
Fix a smatch static checker warning on vdec_vp8_req_if.c. Which leads to a kernel crash when fb is NULL.
--- .../mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c +7 -3
@@ -334,14 +334,18 @@ static int vdec_vp8_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs, src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer); fb = inst->ctx->dev->vdec_pdata->get_cap_buffer (inst->ctx); - dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer); +if (!fb) { +mtk_vdec_err (inst->ctx,"fb buffer is NULL" ); +return -ENOMEM ; + } - y_fb_dma = fb ? (u64 )fb->base_y.dma_addr :0 ; + dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer); + y_fb_dma = fb->base_y.dma_addr;if (inst->ctx->q_data[MTK_Q_DATA_DST ].fmt->num_planes ==1 ) c_fb_dma = y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;else - c_fb_dma = fb ? (u64 )fb->base_c.dma_addr :0 ; + c_fb_dma = fb->base_c.dma_addr; inst->vsi->dec.bs_dma = (u64 )bs->dma_addr; inst->vsi->dec.bs_sz = bs->size;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 354/634 media: mediatek: vcodec: Fix H264 stateless decoder smatch warning
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yunfei Dong <[email protected]>
[ Upstream commit 7878d3a385efab560dce793b595447867fb163f2 ]
Fix a smatch static checker warning on vdec_h264_req_if.c. Which leads to a kernel crash when fb is NULL.
--- .../mediatek/vcodec/decoder/vdec/vdec_h264_req_if.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_if.c +7 -2
@@ -347,11 +347,16 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,return vpu_dec_reset (vpu); fb = inst->ctx->dev->vdec_pdata->get_cap_buffer (inst->ctx); +if (!fb) { +mtk_vdec_err (inst->ctx,"fb buffer is NULL" ); +return -ENOMEM ; + } + src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer); dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer); - y_fb_dma = fb ? (u64 )fb->base_y.dma_addr :0 ; - c_fb_dma = fb ? (u64 )fb->base_c.dma_addr :0 ; + y_fb_dma = fb->base_y.dma_addr; + c_fb_dma = fb->base_c.dma_addr;mtk_vdec_debug (inst->ctx,"+ [%d] FB y_dma=%llx c_dma=%llx va=%p" , inst->num_nalu, y_fb_dma, c_fb_dma, fb);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 355/634 RDMA/rtrs: Reset hb_missed_cnt after receiving other traffic from peer
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jack Wang <[email protected]>
[ Upstream commit 3258cbbd86deaa2675e1799bc3d18bd1ef472641 ]
Reset hb_missed_cnt after receiving traffic from other peer, so hb is more robust again high load on host or network.
--- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 3 ++- drivers/infiniband/ulp/rtrs/rtrs-srv.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
drivers/infiniband/ulp/rtrs/rtrs-clt.c +2 -1
@@ -626,6 +626,7 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)*/ if (WARN_ON (wc->wr_cqe->done != rtrs_clt_rdma_done))return ; + clt_path->s.hb_missed_cnt =0 ;rtrs_from_imm (be32_to_cpu (wc->ex.imm_data), &imm_type, &imm_payload); if (imm_type == RTRS_IO_RSP_IMM ||
@@ -643,7 +644,6 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)return rtrs_clt_recv_done (con, wc); }else if (imm_type ==RTRS_HB_ACK_IMM ) {WARN_ON (con->c.cid); - clt_path->s.hb_missed_cnt =0 ; clt_path->s.hb_cur_latency =ktime_sub (ktime_get (), clt_path->s.hb_last_sent);if (clt_path->flags &RTRS_MSG_NEW_RKEY_F )
@@ -670,6 +670,7 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)/* * Key invalidations from server side */ + clt_path->s.hb_missed_cnt =0 ;WARN_ON (!(wc->wc_flags &IB_WC_WITH_INVALIDATE || wc->wc_flags &IB_WC_WITH_IMM ));WARN_ON (wc->wr_cqe->done != rtrs_clt_rdma_done);
drivers/infiniband/ulp/rtrs/rtrs-srv.c +1 -0
@@ -1229,6 +1229,7 @@ static void rtrs_srv_rdma_done(struct ib_cq *cq, struct ib_wc *wc)*/ if (WARN_ON (wc->wr_cqe != &io_comp_cqe))return ; + srv_path->s.hb_missed_cnt =0 ; err =rtrs_post_recv_empty (&con->c, &io_comp_cqe);if (err) {rtrs_err (s,"rtrs_post_recv(), err: %d\n" , err);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 356/634 RDMA/rtrs-clt: Reset cid to con_num - 1 to stay in bounds
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Md Haris Iqbal <[email protected]>
[ Upstream commit 3e4289b29e216a55d08a89e126bc0b37cbad9f38 ]
In the function init_conns(), after the create_con() and create_cm() for loop if something fails. In the cleanup for loop after the destroy tag, we access out of bound memory because cid is set to clt_path->s.con_num.
This commits resets the cid to clt_path->s.con_num - 1, to stay in bounds in the cleanup loop later.
--- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/infiniband/ulp/rtrs/rtrs-clt.c +6 -0
@@ -2347,6 +2347,12 @@ static int init_conns(struct rtrs_clt_path *clt_path)if (err) goto destroy; } + +/* +* Set the cid to con_num - 1, since if we fail later, we want to stay in bounds. +*/ + cid = clt_path->s.con_num -1 ; + err =alloc_path_reqs (clt_path);if (err) goto destroy;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 357/634 clk: ti: dra7-atl: Fix leak of of_nodes
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
[ Upstream commit 9d6e9f10e2e031fb7bfb3030a7d1afc561a28fea ]
This fix leaking the of_node references in of_dra7_atl_clk_probe().
The docs for of_parse_phandle_with_args() say that the caller must call of_node_put() on the returned node. This adds the missing of_node_put() to fix the leak.
--- drivers/clk/ti/clk-dra7-atl.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/ti/clk-dra7-atl.c +1 -0
@@ -240,6 +240,7 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev) } clk =of_clk_get_from_provider (&clkspec); +of_node_put (clkspec.np);if (IS_ERR (clk)) {pr_err ("%s: failed to get atl clock %d from provider\n" , __func__, i);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 358/634 clk: starfive: Use pm_runtime_resume_and_get to fix pm_runtime_get_sync() usage
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuntao Liu <[email protected]>
[ Upstream commit 55c312c1b2be6d43e39c280ad6ab4b711e545b89 ]
We need to call pm_runtime_put_noidle() when pm_runtime_get_sync() fails, so use pm_runtime_resume_and_get() instead. this function will handle this.
--- drivers/clk/starfive/clk-starfive-jh7110-vout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/starfive/clk-starfive-jh7110-vout.c +1 -1
@@ -145,7 +145,7 @@ static int jh7110_voutcrg_probe(struct platform_device *pdev)/* enable power domain and clocks */ pm_runtime_enable (priv->dev); - ret =pm_runtime_get_sync (priv->dev); + ret =pm_runtime_resume_and_get (priv->dev);if (ret <0 )return dev_err_probe (priv->dev, ret,"failed to turn on power\n" );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 359/634 clk: rockchip: rk3588: Fix 32k clock name for pmu_24m_32k_100m_src_p
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Shiyan <[email protected]>
[ Upstream commit 0d02e8d284a45bfa8997ebe8764437b8eb6b108b ]
The 32kHz input clock is named "xin32k" in the driver, so the name "32k" appears to be a typo in this case. Lets fix this.
--- drivers/clk/rockchip/clk-rk3588.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/rockchip/clk-rk3588.c +1 -1
@@ -526,7 +526,7 @@ PNAME(pmu_200m_100m_p) = { "clk_pmu1_200m_src", "clk_pmu1_100m_src" };PNAME (pmu_300m_24m_p) = {"clk_300m_src" ,"xin24m" };PNAME (pmu_400m_24m_p) = {"clk_400m_src" ,"xin24m" };PNAME (pmu_100m_50m_24m_src_p) = {"clk_pmu1_100m_src" ,"clk_pmu1_50m_src" ,"xin24m" }; -PNAME (pmu_24m_32k_100m_src_p) = {"xin24m" ,"32k" ,"clk_pmu1_100m_src" }; +PNAME (pmu_24m_32k_100m_src_p) = {"xin24m" ,"xin32k" ,"clk_pmu1_100m_src" };PNAME (hclk_pmu1_root_p) = {"clk_pmu1_200m_src" ,"clk_pmu1_100m_src" ,"clk_pmu1_50m_src" ,"xin24m" };PNAME (hclk_pmu_cm0_root_p) = {"clk_pmu1_400m_src" ,"clk_pmu1_200m_src" ,"clk_pmu1_100m_src" ,"xin24m" };PNAME (mclk_pdm0_p) = {"clk_pmu1_300m_src" ,"clk_pmu1_200m_src" };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 360/634 nfsd: remove unneeded EEXIST error check in nfsd_do_file_acquire
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
[ Upstream commit 81a95c2b1d605743220f28db04b8da13a65c4059 ]
Given that we do the search and insertion while holding the i_lock, I don't think it's possible for us to get EEXIST here. Remove this case.
--- fs/nfsd/filecache.c | 2 -- 1 file changed, 2 deletions(-)
fs/nfsd/filecache.c +0 -2
@@ -1035,8 +1035,6 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,if (likely (ret ==0 )) goto open_file; -if (ret == -EEXIST ) - goto retry;trace_nfsd_file_insert_err (rqstp, inode, may_flags, ret); status = nfserr_jukebox; goto construction_err;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 361/634 nfsd: fix refcount leak when file is unhashed after being found
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
[ Upstream commit 8a7926176378460e0d91e02b03f0ff20a8709a60 ]
If we wait_for_construction and find that the file is no longer hashed, and we're going to retry the open, the old nfsd_file reference is currently leaked. Put the reference before retrying.
--- fs/nfsd/filecache.c | 1 + 1 file changed, 1 insertion(+)
fs/nfsd/filecache.c +1 -0
@@ -1049,6 +1049,7 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, status = nfserr_jukebox; goto construction_err; } +nfsd_file_put (nf); open_retry = false;fh_put (fhp); goto retry;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 362/634 pinctrl: mvebu: Fix devinit_dove_pinctrl_probe function
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Jianzheng <[email protected]>
[ Upstream commit c25478419f6fd3f74c324a21ec007cf14f2688d7 ]
When an error occurs during the execution of the function __devinit_dove_pinctrl_probe, the clk is not properly disabled.
Fix this by calling clk_disable_unprepare before return.
--- drivers/pinctrl/mvebu/pinctrl-dove.c | 42 +++++++++++++++++++--------- 1 file changed, 29 insertions(+), 13 deletions(-)
drivers/pinctrl/mvebu/pinctrl-dove.c +29 -13
@@ -767,7 +767,7 @@ static int dove_pinctrl_probe(struct platform_device *pdev)struct resource fb_res;struct mvebu_mpp_ctrl_data *mpp_data;void __iomem *base; -int i; +int i, ret; pdev->dev.platform_data = (void *)device_get_match_data (&pdev->dev);
@@ -783,13 +783,17 @@ static int dove_pinctrl_probe(struct platform_device *pdev)clk_prepare_enable (clk); base =devm_platform_get_and_ioremap_resource (pdev,0 , &mpp_res); -if (IS_ERR (base)) -return PTR_ERR (base); +if (IS_ERR (base)) { + ret =PTR_ERR (base); + goto err_probe; + } mpp_data =devm_kcalloc (&pdev->dev, dove_pinctrl_info.ncontrols,sizeof (*mpp_data),GFP_KERNEL ); -if (!mpp_data) -return -ENOMEM ; +if (!mpp_data) { + ret = -ENOMEM ; + goto err_probe; + } dove_pinctrl_info.control_data = mpp_data;for (i =0 ; i <ARRAY_SIZE (dove_mpp_controls); i++)
@@ -808,8 +812,10 @@ static int dove_pinctrl_probe(struct platform_device *pdev) } mpp4_base =devm_ioremap_resource (&pdev->dev, res); -if (IS_ERR (mpp4_base)) -return PTR_ERR (mpp4_base); +if (IS_ERR (mpp4_base)) { + ret =PTR_ERR (mpp4_base); + goto err_probe; + } res =platform_get_resource (pdev,IORESOURCE_MEM ,2 );if (!res) {
@@ -820,8 +826,10 @@ static int dove_pinctrl_probe(struct platform_device *pdev) } pmu_base =devm_ioremap_resource (&pdev->dev, res); -if (IS_ERR (pmu_base)) -return PTR_ERR (pmu_base); +if (IS_ERR (pmu_base)) { + ret =PTR_ERR (pmu_base); + goto err_probe; + } gconfmap =syscon_regmap_lookup_by_compatible ("marvell,dove-global-config" );if (IS_ERR (gconfmap)) {
@@ -831,12 +839,17 @@ static int dove_pinctrl_probe(struct platform_device *pdev)adjust_resource (&fb_res, (mpp_res->start &INT_REGS_MASK ) +GC_REGS_OFFS ,0x14 ); gc_base =devm_ioremap_resource (&pdev->dev, &fb_res); -if (IS_ERR (gc_base)) -return PTR_ERR (gc_base); +if (IS_ERR (gc_base)) { + ret =PTR_ERR (gc_base); + goto err_probe; + } + gconfmap =devm_regmap_init_mmio (&pdev->dev, gc_base, &gc_regmap_config); -if (IS_ERR (gconfmap)) -return PTR_ERR (gconfmap); +if (IS_ERR (gconfmap)) { + ret =PTR_ERR (gconfmap); + goto err_probe; + } }/* Warn on any missing DT resource */
@@ -844,6 +857,9 @@ static int dove_pinctrl_probe(struct platform_device *pdev)dev_warn (&pdev->dev,FW_BUG "Missing pinctrl regs in DTB. Please update your firmware.\n" );return mvebu_pinctrl_probe (pdev); +err_probe: +clk_disable_unprepare (clk); +return ret; }static struct platform_driver dove_pinctrl_driver = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 363/634 IB/core: Fix ib_cache_setup_one error flow cleanup
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Patrisious Haddad <[email protected]>
[ Upstream commit 1403c8b14765eab805377dd3b75e96ace8747aed ]
When ib_cache_update return an error, we exit ib_cache_setup_one instantly with no proper cleanup, even though before this we had already successfully done gid_table_setup_one, that results in the kernel WARN below.
Do proper cleanup using gid_table_cleanup_one before returning the err in order to fix the issue.
WARNING: CPU: 4 PID: 922 at drivers/infiniband/core/cache.c:806 gid_table_release_one+0x181/0x1a0 Modules linked in: CPU: 4 UID: 0 PID: 922 Comm: c_repro Not tainted 6.11.0-rc1+ #3 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 RIP: 0010:gid_table_release_one+0x181/0x1a0 Code: 44 8b 38 75 0c e8 2f cb 34 ff 4d 8b b5 28 05 00 00 e8 23 cb 34 ff 44 89 f9 89 da 4c 89 f6 48 c7 c7 d0 58 14 83 e8 4f de 21 ff <0f> 0b 4c 8b 75 30 e9 54 ff ff ff 48 8 3 c4 10 5b 5d 41 5c 41 5d 41 RSP: 0018:ffffc90002b835b0 EFLAGS: 00010286 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff811c8527 RDX: 0000000000000000 RSI: ffffffff811c8534 RDI: 0000000000000001 RBP: ffff8881011b3d00 R08: ffff88810b3abe00 R09: 205d303839303631 R10: 666572207972746e R11: 72746e6520444947 R12: 0000000000000001 R13: ffff888106390000 R14: ffff8881011f2110 R15: 0000000000000001 FS: 00007fecc3b70800(0000) GS:ffff88813bd00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020000340 CR3: 000000010435a001 CR4: 00000000003706b0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> ? show_regs+0x94/0xa0 ? __warn+0x9e/0x1c0 ? gid_table_release_one+0x181/0x1a0 ? report_bug+0x1f9/0x340 ? gid_table_release_one+0x181/0x1a0 ? handle_bug+0xa2/0x110 ? exc_invalid_op+0x31/0xa0 ? asm_exc_invalid_op+0x16/0x20 ? __warn_printk+0xc7/0x180 ? __warn_printk+0xd4/0x180 ? gid_table_release_one+0x181/0x1a0 ib_device_release+0x71/0xe0 ? __pfx_ib_device_release+0x10/0x10 device_release+0x44/0xd0 kobject_put+0x135/0x3d0 put_device+0x20/0x30 rxe_net_add+0x7d/0xa0 rxe_newlink+0xd7/0x190 nldev_newlink+0x1b0/0x2a0 ? __pfx_nldev_newlink+0x10/0x10 rdma_nl_rcv_msg+0x1ad/0x2e0 rdma_nl_rcv_skb.constprop.0+0x176/0x210 netlink_unicast+0x2de/0x400 netlink_sendmsg+0x306/0x660 __sock_sendmsg+0x110/0x120 ____sys_sendmsg+0x30e/0x390 ___sys_sendmsg+0x9b/0xf0 ? kstrtouint+0x6e/0xa0 ? kstrtouint_from_user+0x7c/0xb0 ? get_pid_task+0xb0/0xd0 ? proc_fail_nth_write+0x5b/0x140 ? __fget_light+0x9a/0x200 ? preempt_count_add+0x47/0xa0 __sys_sendmsg+0x61/0xd0 do_syscall_64+0x50/0x110 entry_SYSCALL_64_after_hwframe+0x76/0x7e
--- drivers/infiniband/core/cache.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/infiniband/core/cache.c +3 -1
@@ -1640,8 +1640,10 @@ int ib_cache_setup_one(struct ib_device *device) rdma_for_each_port (device, p) { err =ib_cache_update (device, p, true, true, true); -if (err) +if (err) { +gid_table_cleanup_one (device);return err; + } }return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 364/634 dt-bindings: PCI: layerscape-pci: Replace fsl,lx2160a-pcie with fsl,lx2160ar2-pcie
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
[ Upstream commit 1a1bf58897d20fc38b454dfecd2771e142d36966 ]
The fsl,lx2160a-pcie compatible is used for mobivel according to the Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt file.
Whereas the fsl,layerscape-pcie is used for DesignWare PCIe controller binding.
So change it to fsl,lx2160ar2-pcie and allow a fall back to fsl,ls2088a-pcie.
While at it, sort compatible string.
--- .../bindings/pci/fsl,layerscape-pcie.yaml | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-)
Documentation/devicetree/bindings/pci/fsl,layerscape-pcie.yaml +14 -12
@@ -22,18 +22,20 @@ description: properties: compatible: - enum: - - fsl,ls1021a-pcie - - fsl,ls2080a-pcie - - fsl,ls2085a-pcie - - fsl,ls2088a-pcie - - fsl,ls1088a-pcie - - fsl,ls1046a-pcie - - fsl,ls1043a-pcie - - fsl,ls1012a-pcie - - fsl,ls1028a-pcie - - fsl,lx2160a-pcie - + oneOf: + - enum: + - fsl,ls1012a-pcie + - fsl,ls1021a-pcie + - fsl,ls1028a-pcie + - fsl,ls1043a-pcie + - fsl,ls1046a-pcie + - fsl,ls1088a-pcie + - fsl,ls2080a-pcie + - fsl,ls2085a-pcie + - fsl,ls2088a-pcie + - items: + - const: fsl,lx2160ar2-pcie + - const: fsl,ls2088a-pcie reg: maxItems: 2
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 365/634 iommufd: Check the domain owner of the parent before creating a nesting domain
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit 73183ad6ea51029d04b098286dcee98d715015f1 ]
This check was missed, before we can pass a struct iommu_domain to a driver callback we need to validate that the domain was created by that driver.
--- drivers/iommu/iommufd/hw_pagetable.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/iommu/iommufd/hw_pagetable.c +2 -1
@@ -215,7 +215,8 @@ iommufd_hwpt_nested_alloc(struct iommufd_ctx *ictx,if (flags || !user_data->len || !ops->domain_alloc_user)return ERR_PTR (-EOPNOTSUPP ); -if (parent->auto_domain || !parent->nest_parent) +if (parent->auto_domain || !parent->nest_parent || + parent->common.domain->owner != ops)return ERR_PTR (-EINVAL ); hwpt_nested = __iommufd_object_alloc(
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 366/634 PCI: kirin: Fix buffer overflow in kirin_pcie_parse_port()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexandra Diupina <[email protected]>
[ Upstream commit c500a86693a126c9393e602741e348f80f1b0fc5 ]
Within kirin_pcie_parse_port(), the pcie->num_slots is compared to pcie->gpio_id_reset size (MAX_PCI_SLOTS) which is correct and would lead to an overflow.
Thus, fix condition to pcie->num_slots + 1 >= MAX_PCI_SLOTS and move pcie->num_slots increment below the if-statement to avoid out-of-bounds array access.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/pci/controller/dwc/pcie-kirin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/pci/controller/dwc/pcie-kirin.c +2 -2
@@ -412,12 +412,12 @@ static int kirin_pcie_parse_port(struct kirin_pcie *pcie,if (pcie->gpio_id_reset[i] <0 )continue ; - pcie->num_slots++; -if (pcie->num_slots >MAX_PCI_SLOTS ) { +if (pcie->num_slots +1 >=MAX_PCI_SLOTS ) {dev_err (dev,"Too many PCI slots!\n" ); ret = -EINVAL ; goto put_node; } + pcie->num_slots++; ret =of_pci_get_devfn (child);if (ret <0 ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 367/634 RDMA/erdma: Return QP state in erdma_query_qp
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cheng Xu <[email protected]>
[ Upstream commit e77127ff6416b17e0b3e630ac46ee5c9a6570f57 ]
Fix qp_state and cur_qp_state to return correct values in struct ib_qp_attr.
--- drivers/infiniband/hw/erdma/erdma_verbs.c | 25 ++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
drivers/infiniband/hw/erdma/erdma_verbs.c +24 -1
@@ -1544,11 +1544,31 @@ int erdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,return ret; } +static enum ib_qp_state query_qp_state (struct erdma_qp *qp) +{ +switch (qp->attrs.state) { +case ERDMA_QP_STATE_IDLE : +return IB_QPS_INIT ; +case ERDMA_QP_STATE_RTR : +return IB_QPS_RTR ; +case ERDMA_QP_STATE_RTS : +return IB_QPS_RTS ; +case ERDMA_QP_STATE_CLOSING : +return IB_QPS_ERR ; +case ERDMA_QP_STATE_TERMINATE : +return IB_QPS_ERR ; +case ERDMA_QP_STATE_ERROR : +return IB_QPS_ERR ; +default : +return IB_QPS_ERR ; + } +} +int erdma_query_qp (struct ib_qp *ibqp,struct ib_qp_attr *qp_attr,int qp_attr_mask,struct ib_qp_init_attr *qp_init_attr) { -struct erdma_qp *qp;struct erdma_dev *dev; +struct erdma_qp *qp;if (ibqp && qp_attr && qp_init_attr) { qp =to_eqp (ibqp);
@@ -1575,6 +1595,9 @@ int erdma_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, qp_init_attr->cap = qp_attr->cap; + qp_attr->qp_state =query_qp_state (qp); + qp_attr->cur_qp_state =query_qp_state (qp); +return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 368/634 RDMA/mlx5: Fix counter update on MR cache mkey creation
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Guralnik <[email protected]>
[ Upstream commit 6f5cd6ac9a4201e4ba6f10b76a9da8044d6e38b0 ]
After an mkey is created, update the counter for pending mkeys before reshceduling the work that is filling the cache.
Rescheduling the work with a full MR cache entry and a wrong 'pending' counter will cause us to miss disabling the fill_to_high_water flag. Thus leaving the cache full but with an indication that it's still needs to be filled up to it's full size (2 * limit).
Next time an mkey will be taken from the cache, we'll unnecessarily continue the process of filling the cache to it's full size.
--- drivers/infiniband/hw/mlx5/mr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/mlx5/mr.c +1 -1
@@ -211,9 +211,9 @@ static void create_mkey_callback(int status, struct mlx5_async_work *context)spin_lock_irqsave (&ent->mkeys_queue.lock, flags);push_mkey_locked (ent, mkey_out->mkey); + ent->pending--;/* If we are doing fill_to_high_water then keep going. */ queue_adjust_cache_locked (ent); - ent->pending--;spin_unlock_irqrestore (&ent->mkeys_queue.lock, flags);kfree (mkey_out); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 369/634 RDMA/mlx5: Limit usage of over-sized mkeys from the MR cache
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Guralnik <[email protected]>
[ Upstream commit ee6d57a2e13d11ce9050cfc3e3b69ef707a44a63 ]
When searching the MR cache for suitable cache entries, don't use mkeys larger than twice the size required for the MR.
This should ensure the usage of mkeys closer to the minimal required size and reduce memory waste.
On driver init we create entries for mkeys with clear attributes and powers of 2 sizes from 4 to the max supported size.
This solves the issue for anyone using mkeys that fit these requirements.
In the use case where an MR is registered with different attributes, like an access flag we can't UMR, we'll create a new cache entry to store it upon dereg.
Without this fix, any later registration with same attributes and smaller size will use the newly created cache entry and it's mkeys, disregarding the memory waste of using mkeys larger than required.
For example, one worst-case scenario can be when registering and deregistering a 1GB mkey with ATS enabled which will cause the creation of a new cache entry to hold those type of mkeys. A user registering a 4k MR with ATS will end up using the new cache entry and an mkey that can support a 1GB MR, thus wasting x250k memory than actually needed in the HW.
Additionally, allow all small registration to use the smallest size cache entry that is initialized on driver load even if size is larger than twice the required size.
--- drivers/infiniband/hw/mlx5/mr.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/infiniband/hw/mlx5/mr.c +12 -2
@@ -48,6 +48,7 @@ enum { MAX_PENDING_REG_MR = 8, }; +#define MLX5_MR_CACHE_PERSISTENT_ENTRY_MIN_DESCS 4#define MLX5_UMR_ALIGN 2048 static void
@@ -659,6 +660,7 @@ mkey_cache_ent_from_rb_key(struct mlx5_ib_dev *dev, {struct rb_node *node = dev->cache.rb_root.rb_node;struct mlx5_cache_ent *cur, *smallest =NULL ; +u64 ndescs_limit;int cmp;/*
@@ -677,10 +679,18 @@ mkey_cache_ent_from_rb_key(struct mlx5_ib_dev *dev,return cur; } +/* +* Limit the usage of mkeys larger than twice the required size while +* also allowing the usage of smallest cache entry for small MRs. +*/ + ndescs_limit =max_t (u64, rb_key.ndescs *2 , +MLX5_MR_CACHE_PERSISTENT_ENTRY_MIN_DESCS ); +return (smallest && smallest->rb_key.access_mode == rb_key.access_mode && smallest->rb_key.access_flags == rb_key.access_flags && - smallest->rb_key.ats == rb_key.ats) ? + smallest->rb_key.ats == rb_key.ats && + smallest->rb_key.ndescs <= ndescs_limit) ? smallest :NULL ; }
@@ -962,7 +972,7 @@ int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev)mlx5_mkey_cache_debugfs_init (dev);mutex_lock (&cache->rb_lock);for (i =0 ; i <=mkey_cache_max_order (dev); i++) { - rb_key.ndescs =1 << (i +2 ); + rb_key.ndescs =MLX5_MR_CACHE_PERSISTENT_ENTRY_MIN_DESCS << i; ent =mlx5r_cache_create_ent_locked (dev, rb_key, true);if (IS_ERR (ent)) { ret =PTR_ERR (ent);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 370/634 RDMA/mlx5: Drop redundant work canceling from clean_keys()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Guralnik <[email protected]>
[ Upstream commit 30e6bd8d3b5639f8f4261e5e6c0917ce264b8dc2 ]
The canceling of dealyed work in clean_keys() is a leftover from years back and was added to prevent races in the cleanup process of MR cache. The cleanup process was rewritten a few years ago and the canceling of delayed work and flushing of workqueue was added before the call to clean_keys().
Stable-dep-of: 7ebb00cea49d ("RDMA/mlx5: Fix MR cache temp entries cleanup")
--- drivers/infiniband/hw/mlx5/mr.c | 1 - 1 file changed, 1 deletion(-)
drivers/infiniband/hw/mlx5/mr.c +0 -1
@@ -779,7 +779,6 @@ static void clean_keys(struct mlx5_ib_dev *dev, struct mlx5_cache_ent *ent) {u32 mkey; -cancel_delayed_work (&ent->dwork);spin_lock_irq (&ent->mkeys_queue.lock);while (ent->mkeys_queue.ci) { mkey =pop_mkey_locked (ent);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 371/634 RDMA/mlx5: Fix MR cache temp entries cleanup
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Guralnik <[email protected]>
[ Upstream commit 7ebb00cea49db641b458edef0ede389f7004821d ]
Fix the cleanup of the temp cache entries that are dynamically created in the MR cache.
The cleanup of the temp cache entries is currently scheduled only when a new entry is created. Since in the cleanup of the entries only the mkeys are destroyed and the cache entry stays in the cache, subsequent registrations might reuse the entry and it will eventually be filled with new mkeys without cleanup ever getting scheduled again.
On workloads that register and deregister MRs with a wide range of properties we see the cache ends up holding many cache entries, each holding the max number of mkeys that were ever used through it.
Additionally, as the cleanup work is scheduled to run over the whole cache, any mkey that is returned to the cache after the cleanup was scheduled will be held for less than the intended 30 seconds timeout.
Solve both issues by dropping the existing remove_ent_work and reusing the existing per-entry work to also handle the temp entries cleanup.
Schedule the work to run with a 30 seconds delay every time we push an mkey to a clean temp entry.
This ensures the cleanup runs on each entry only 30 seconds after the first mkey was pushed to an empty entry.
As we have already been distinguishing between persistent and temp entries when scheduling the cache_work_func, it is not being scheduled in any other flows for the temp entries.
Another benefit from moving to a per-entry cleanup is we now not required to hold the rb_tree mutex, thus enabling other flow to run concurrently.
--- drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 +- drivers/infiniband/hw/mlx5/mr.c | 82 +++++++++++----------------- 2 files changed, 32 insertions(+), 52 deletions(-)
drivers/infiniband/hw/mlx5/mlx5_ib.h +1 -1
@@ -795,6 +795,7 @@ struct mlx5_cache_ent { u8 is_tmp:1; u8 disabled:1; u8 fill_to_high_water:1; + u8 tmp_cleanup_scheduled:1;/* * - limit is the low water mark for stored mkeys, 2* limit is the
@@ -826,7 +827,6 @@ struct mlx5_mkey_cache {struct mutex rb_lock;struct dentry *fs_root;unsigned long last_add; -struct delayed_work remove_ent_dwork; };struct mlx5_ib_port_resources {
drivers/infiniband/hw/mlx5/mr.c +31 -51
131 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 372/634 watchdog: imx_sc_wdt: Dont disable WDT in suspend
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Blixt <[email protected]>
[ Upstream commit 2d9d6d300fb0a4ae4431bb308027ac9385746d42 ]
Parts of the suspend and resume chain is left unprotected if we disable the WDT here.
Quoted 1 line
From experiments we can see that the SCU disables and re-enables the WDT
when we enter and leave suspend to ram. By not touching the WDT here we are protected by the WDT all the way to the SCU.
--- drivers/watchdog/imx_sc_wdt.c | 24 ------------------------ 1 file changed, 24 deletions(-)
drivers/watchdog/imx_sc_wdt.c +0 -24
@@ -216,29 +216,6 @@ static int imx_sc_wdt_probe(struct platform_device *pdev)return devm_watchdog_register_device (dev, wdog); } -static int __maybe_unused imx_sc_wdt_suspend (struct device *dev) -{ -struct imx_sc_wdt_device *imx_sc_wdd =dev_get_drvdata (dev); - -if (watchdog_active (&imx_sc_wdd->wdd)) -imx_sc_wdt_stop (&imx_sc_wdd->wdd); - -return 0 ; -} - -static int __maybe_unused imx_sc_wdt_resume (struct device *dev) -{ -struct imx_sc_wdt_device *imx_sc_wdd =dev_get_drvdata (dev); - -if (watchdog_active (&imx_sc_wdd->wdd)) -imx_sc_wdt_start (&imx_sc_wdd->wdd); - -return 0 ; -} - -static SIMPLE_DEV_PM_OPS(imx_sc_wdt_pm_ops, - imx_sc_wdt_suspend, imx_sc_wdt_resume); -static const struct of_device_id imx_sc_wdt_dt_ids[] = { { .compatible ="fsl,imx-sc-wdt" , }, {/* sentinel */ }
@@ -250,7 +227,6 @@ static struct platform_driver imx_sc_wdt_driver = { .driver = { .name = "imx-sc-wdt", .of_match_table = imx_sc_wdt_dt_ids, - .pm = &imx_sc_wdt_pm_ops, }, };module_platform_driver (imx_sc_wdt_driver);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 373/634 RDMA/hns: Dont modify rq next block addr in HIP09 QPC
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxian Huang <[email protected]>
[ Upstream commit 6928d264e328e0cb5ee7663003a6e46e4cba0a7e ]
The field 'rq next block addr' in QPC can be updated by driver only on HIP08. On HIP09 HW updates this field while driver is not allowed.
--- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +8 -6
@@ -4423,12 +4423,14 @@ static int config_qp_rq_buf(struct hns_roce_dev *hr_dev, upper_32_bits(to_hr_hw_page_addr(mtts[0])));hr_reg_clear (qpc_mask,QPC_RQ_CUR_BLK_ADDR_H ); - context->rq_nxt_blk_addr =cpu_to_le32 (to_hr_hw_page_addr (mtts[1 ])); - qpc_mask->rq_nxt_blk_addr =0 ; - -hr_reg_write (context,QPC_RQ_NXT_BLK_ADDR_H , -upper_32_bits (to_hr_hw_page_addr (mtts[1 ]))); -hr_reg_clear (qpc_mask,QPC_RQ_NXT_BLK_ADDR_H ); +if (hr_dev->pci_dev->revision ==PCI_REVISION_ID_HIP08 ) { + context->rq_nxt_blk_addr = +cpu_to_le32 (to_hr_hw_page_addr (mtts[1 ])); + qpc_mask->rq_nxt_blk_addr =0 ; +hr_reg_write (context,QPC_RQ_NXT_BLK_ADDR_H , +upper_32_bits (to_hr_hw_page_addr (mtts[1 ]))); +hr_reg_clear (qpc_mask,QPC_RQ_NXT_BLK_ADDR_H ); + }return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 374/634 RDMA/hns: Fix Use-After-Free of rsv_qp on HIP08
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: wenglianfa <[email protected]>
[ Upstream commit fd8489294dd2beefb70f12ec4f6132aeec61a4d0 ]
Currently rsv_qp is freed before ib_unregister_device() is called on HIP08. During the time interval, users can still dereg MR and rsv_qp will be used in this process, leading to a UAF. Move the release of rsv_qp after calling ib_unregister_device() to fix it.
--- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +3 -3
@@ -2972,6 +2972,9 @@ static int hns_roce_v2_init(struct hns_roce_dev *hr_dev)static void hns_roce_v2_exit (struct hns_roce_dev *hr_dev) { +if (hr_dev->pci_dev->revision ==PCI_REVISION_ID_HIP08 ) +free_mr_exit (hr_dev); +hns_roce_function_clear (hr_dev);if (!hr_dev->is_vf)
@@ -6951,9 +6954,6 @@ static void __hns_roce_hw_v2_uninit_instance(struct hnae3_handle *handle, hr_dev->state =HNS_ROCE_DEVICE_STATE_UNINIT ;hns_roce_handle_device_err (hr_dev); -if (hr_dev->pci_dev->revision ==PCI_REVISION_ID_HIP08 ) -free_mr_exit (hr_dev); -hns_roce_exit (hr_dev);kfree (hr_dev->priv);ib_dealloc_device (&hr_dev->ib_dev);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 375/634 RDMA/hns: Fix the overflow risk of hem_list_calc_ba_range()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: wenglianfa <[email protected]>
[ Upstream commit d586628b169d14bbf36be64d2b3ec9d9d2fe0432 ]
The max value of 'unit' and 'hop_num' is 2^24 and 2, so the value of 'step' may exceed the range of u32. Change the type of 'step' to u64.
--- drivers/infiniband/hw/hns/hns_roce_hem.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/infiniband/hw/hns/hns_roce_hem.c +6 -6
@@ -1041,9 +1041,9 @@ static bool hem_list_is_bottom_bt(int hopnum, int bt_level)* @bt_level: base address table level * @unit: ba entries per bt page */ -static u32 hem_list_calc_ba_range (int hopnum,int bt_level,int unit) +static u64 hem_list_calc_ba_range (int hopnum,int bt_level,int unit) { -u32 step; +u64 step;int max;int i;
@@ -1079,7 +1079,7 @@ int hns_roce_hem_list_calc_root_ba(const struct hns_roce_buf_region *regions, {struct hns_roce_buf_region *r;int total =0 ; -int step; +u64 step;int i;for (i =0 ; i < region_cnt; i++) {
@@ -1110,7 +1110,7 @@ static int hem_list_alloc_mid_bt(struct hns_roce_dev *hr_dev,int ret =0 ;int max_ofs;int level; -u32 step; +u64 step;int end;if (hopnum <=1 )
@@ -1147,7 +1147,7 @@ static int hem_list_alloc_mid_bt(struct hns_roce_dev *hr_dev, } start_aligned = (distance / step) * step + r->offset; - end =min_t (int, start_aligned + step -1 , max_ofs); + end =min_t (u64, start_aligned + step -1 , max_ofs); cur =hem_list_alloc_item (hr_dev, start_aligned, end, unit, true);if (!cur) {
@@ -1235,7 +1235,7 @@ static int setup_middle_bt(struct hns_roce_dev *hr_dev, void *cpu_base,struct hns_roce_hem_item *hem, *temp_hem;int total =0 ;int offset; -int step; +u64 step; step =hem_list_calc_ba_range (r->hopnum,1 , unit);if (step <1 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 376/634 RDMA/hns: Fix spin_unlock_irqrestore() called with IRQs enabled
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengchang Tang <[email protected]>
[ Upstream commit 74d315b5af180220d561684d15897730135733a6 ]
Fix missuse of spin_lock_irq()/spin_unlock_irq() when spin_lock_irqsave()/spin_lock_irqrestore() was hold.
This was discovered through the lock debugging, and the corresponding log is as follows:
raw_local_irq_restore() called with IRQs enabled
WARNING: CPU: 96 PID: 2074 at kernel/locking/irqflag-debug.c:10 warn_bogus_irq_restore+0x30/0x40 ... Call trace: warn_bogus_irq_restore+0x30/0x40 _raw_spin_unlock_irqrestore+0x84/0xc8 add_qp_to_list+0x11c/0x148 [hns_roce_hw_v2] hns_roce_create_qp_common.constprop.0+0x240/0x780 [hns_roce_hw_v2] hns_roce_create_qp+0x98/0x160 [hns_roce_hw_v2] create_qp+0x138/0x258 ib_create_qp_kernel+0x50/0xe8 create_mad_qp+0xa8/0x128 ib_mad_port_open+0x218/0x448 ib_mad_init_device+0x70/0x1f8 add_client_context+0xfc/0x220 enable_device_and_get+0xd0/0x140 ib_register_device.part.0+0xf4/0x1c8 ib_register_device+0x34/0x50 hns_roce_register_device+0x174/0x3d0 [hns_roce_hw_v2] hns_roce_init+0xfc/0x2c0 [hns_roce_hw_v2] __hns_roce_hw_v2_init_instance+0x7c/0x1d0 [hns_roce_hw_v2] hns_roce_hw_v2_init_instance+0x9c/0x180 [hns_roce_hw_v2]
--- drivers/infiniband/hw/hns/hns_roce_qp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/infiniband/hw/hns/hns_roce_qp.c +8 -8
@@ -1460,19 +1460,19 @@ void hns_roce_lock_cqs(struct hns_roce_cq *send_cq, struct hns_roce_cq *recv_cq)__acquire (&send_cq->lock);__acquire (&recv_cq->lock); }else if (unlikely (send_cq !=NULL && recv_cq ==NULL )) { -spin_lock_irq (&send_cq->lock); +spin_lock (&send_cq->lock);__acquire (&recv_cq->lock); }else if (unlikely (send_cq ==NULL && recv_cq !=NULL )) { -spin_lock_irq (&recv_cq->lock); +spin_lock (&recv_cq->lock);__acquire (&send_cq->lock); }else if (send_cq == recv_cq) { -spin_lock_irq (&send_cq->lock); +spin_lock (&send_cq->lock);__acquire (&recv_cq->lock); }else if (send_cq->cqn < recv_cq->cqn) { -spin_lock_irq (&send_cq->lock); +spin_lock (&send_cq->lock);spin_lock_nested (&recv_cq->lock,SINGLE_DEPTH_NESTING ); }else { -spin_lock_irq (&recv_cq->lock); +spin_lock (&recv_cq->lock);spin_lock_nested (&send_cq->lock,SINGLE_DEPTH_NESTING ); } }
@@ -1492,13 +1492,13 @@ void hns_roce_unlock_cqs(struct hns_roce_cq *send_cq,spin_unlock (&recv_cq->lock); }else if (send_cq == recv_cq) {__release (&recv_cq->lock); -spin_unlock_irq (&send_cq->lock); +spin_unlock (&send_cq->lock); }else if (send_cq->cqn < recv_cq->cqn) {spin_unlock (&recv_cq->lock); -spin_unlock_irq (&send_cq->lock); +spin_unlock (&send_cq->lock); }else {spin_unlock (&send_cq->lock); -spin_unlock_irq (&recv_cq->lock); +spin_unlock (&recv_cq->lock); } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 377/634 RDMA/hns: Fix VF triggering PF reset in abnormal interrupt handler
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxian Huang <[email protected]>
[ Upstream commit 4321feefa5501a746ebf6a7d8b59e6b955ae1860 ]
In abnormal interrupt handler, a PF reset will be triggered even if the device is a VF. It should be a VF reset.
--- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +5 -2
@@ -6198,6 +6198,7 @@ static irqreturn_t abnormal_interrupt_basic(struct hns_roce_dev *hr_dev,struct pci_dev *pdev = hr_dev->pci_dev;struct hnae3_ae_dev *ae_dev =pci_get_drvdata (pdev);const struct hnae3_ae_ops *ops = ae_dev->ops; +enum hnae3_reset_type reset_type;irqreturn_t int_work =IRQ_NONE ;u32 int_en;
@@ -6209,10 +6210,12 @@ static irqreturn_t abnormal_interrupt_basic(struct hns_roce_dev *hr_dev,roce_write (hr_dev,ROCEE_VF_ABN_INT_ST_REG ,1 <<HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S ); + reset_type = hr_dev->is_vf ? +HNAE3_VF_FUNC_RESET :HNAE3_FUNC_RESET ; +/* Set reset level for reset_event() */ if (ops->set_default_reset_request) - ops->set_default_reset_request (ae_dev, -HNAE3_FUNC_RESET ); + ops->set_default_reset_request (ae_dev, reset_type);if (ops->reset_event) ops->reset_event (pdev,NULL );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 378/634 RDMA/hns: Fix 1bit-ECC recovery address in non-4K OS
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengchang Tang <[email protected]>
[ Upstream commit ce196f6297c7f3ab7780795e40efd6c521f60c8b ]
The 1bit-ECC recovery address read from HW only contain bits 64:12, so it should be fixed left-shifted 12 bits when used.
Currently, the driver will shift the address left by PAGE_SHIFT when used, which is wrong in non-4K OS.
--- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +1 -1
@@ -6285,7 +6285,7 @@ static u64 fmea_get_ram_res_addr(u32 res_type, __le64 *data) res_type == ECC_RESOURCE_SCCC)return le64_to_cpu (*data); -return le64_to_cpu (*data) <<PAGE_SHIFT ; +return le64_to_cpu (*data) <<HNS_HW_PAGE_SHIFT ; } static int fmea_recover_others(struct hns_roce_dev *hr_dev, u32 res_type,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 379/634 RDMA/hns: Optimize hem allocation performance
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxian Huang <[email protected]>
[ Upstream commit fe51f6254d81f5a69c31df16353d6539b2b51630 ]
When allocating MTT hem, for each hop level of each hem that is being allocated, the driver iterates the hem list to find out whether the bt page has been allocated in this hop level. If not, allocate a new one and splice it to the list. The time complexity is O(n^2) in worst cases.
Currently the allocation for-loop uses 'unit' as the step size. This actually has taken into account the reuse of last-hop-level MTT bt pages by multiple buffer pages. Thus pages of last hop level will never have been allocated, so there is no need to iterate the hem list in last hop level.
Removing this unnecessary iteration can reduce the time complexity to O(n).
--- drivers/infiniband/hw/hns/hns_roce_hem.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/infiniband/hw/hns/hns_roce_hem.c +6 -4
@@ -1134,10 +1134,12 @@ static int hem_list_alloc_mid_bt(struct hns_roce_dev *hr_dev,/* config L1 bt to last bt and link them to corresponding parent */ for (level =1 ; level < hopnum; level++) { - cur =hem_list_search_item (&mid_bt[level], offset); -if (cur) { - hem_ptrs[level] = cur; -continue ; +if (!hem_list_is_bottom_bt (hopnum, level)) { + cur =hem_list_search_item (&mid_bt[level], offset); +if (cur) { + hem_ptrs[level] = cur; +continue ; + } } step =hem_list_calc_ba_range (hopnum, level, unit);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 380/634 RDMA/hns: Fix restricted __le16 degrades to integer issue
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxian Huang <[email protected]>
[ Upstream commit f4ccc0a2a0c5977540f519588636b5bc81aae2db ]
Fix sparse warnings: restricted __le16 degrades to integer.
--- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +2 -2
@@ -1681,8 +1681,8 @@ static int hns_roce_hw_v2_query_counter(struct hns_roce_dev *hr_dev,for (i =0 ; i <HNS_ROCE_HW_CNT_TOTAL && i < *num_counters; i++) { bd_idx = i /CNT_PER_DESC ; -if (!(desc[bd_idx].flag &HNS_ROCE_CMD_FLAG_NEXT ) && - bd_idx !=HNS_ROCE_HW_CNT_TOTAL /CNT_PER_DESC ) +if (bd_idx !=HNS_ROCE_HW_CNT_TOTAL /CNT_PER_DESC && + !(desc[bd_idx].flag &cpu_to_le16 (HNS_ROCE_CMD_FLAG_NEXT )))break ; cnt_data = (__le64 *)&desc[bd_idx].data[0 ];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 381/634 RDMA/mlx5: Obtain upper net device only when needed
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Bloch <[email protected]>
[ Upstream commit 3ed7f9e239938a0cfaf3689e2f545229ecabec06 ]
Report the upper device's state as the RDMA port state only in RoCE LAG or switchdev LAG.
--- drivers/infiniband/hw/mlx5/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/mlx5/main.c +1 -1
@@ -542,7 +542,7 @@ static int mlx5_query_port_roce(struct ib_device *device, u32 port_num,if (!ndev) goto out; -if (dev->lag_active) { +if (mlx5_lag_is_roce (mdev) ||mlx5_lag_is_sriov (mdev)) {rcu_read_lock (); upper =netdev_master_upper_dev_get_rcu (ndev);if (upper) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 382/634 PCI: qcom-ep: Enable controller resources like PHY only after refclk is available
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manivannan Sadhasivam <[email protected]>
[ Upstream commit d3745e3ae6c0eec517d431be926742b6e8b9b64a ]
qcom_pcie_enable_resources() is called by qcom_pcie_ep_probe() and it enables the controller resources like clocks, regulator, PHY. On one of the new unreleased Qcom SoC, PHY enablement depends on the active refclk. And on all of the supported Qcom endpoint SoCs, refclk comes from the host (RC). So calling qcom_pcie_enable_resources() without refclk causes the NoC (Network On Chip) error in the endpoint SoC and in turn results in a whole SoC crash and rebooting into EDL (Emergency Download) mode which is an unrecoverable state.
But qcom_pcie_enable_resources() is already called by qcom_pcie_perst_deassert() when PERST# is deasserted, and refclk is available at that time.
Hence, remove the unnecessary call to qcom_pcie_enable_resources() from qcom_pcie_ep_probe() to prevent the above mentioned crash.
It should be noted that this commit prevents the crash only under normal working condition (booting endpoint before host), but the crash may also occur if PERST# assert happens at the wrong time. For avoiding the crash completely, it is recommended to use SRIS mode which allows the endpoint SoC to generate its own refclk. The driver is not supporting SRIS mode currently, but will be added in the future.
--- drivers/pci/controller/dwc/pcie-qcom-ep.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
drivers/pci/controller/dwc/pcie-qcom-ep.c +4 -10
@@ -816,21 +816,15 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev)if (ret)return ret; - ret =qcom_pcie_enable_resources (pcie_ep); -if (ret) { -dev_err (dev,"Failed to enable resources: %d\n" , ret); -return ret; - } - ret =dw_pcie_ep_init (&pcie_ep->pci.ep);if (ret) {dev_err (dev,"Failed to initialize endpoint: %d\n" , ret); - goto err_disable_resources; +return ret; } ret =qcom_pcie_ep_enable_irq_resources (pdev, pcie_ep);if (ret) - goto err_disable_resources; + goto err_ep_deinit; name =devm_kasprintf (dev,GFP_KERNEL ,"%pOFP" , dev->of_node);if (!name) {
@@ -847,8 +841,8 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev)disable_irq (pcie_ep->global_irq);disable_irq (pcie_ep->perst_irq); -err_disable_resources: -qcom_pcie_disable_resources (pcie_ep); +err_ep_deinit: +dw_pcie_ep_deinit (&pcie_ep->pci.ep);return ret; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 383/634 riscv: Fix fp alignment bug in perf_callchain_user()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit 22ab08955ea13be04a8efd20cc30890e0afaa49c ]
The standard RISC-V calling convention said:
"The stack grows downward and the stack pointer is always kept 16-byte aligned".
So perf_callchain_user() should check whether 16-byte aligned for fp.
--- arch/riscv/kernel/perf_callchain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/kernel/perf_callchain.c +1 -1
@@ -62,7 +62,7 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,perf_callchain_store (entry, regs->epc); fp =user_backtrace (entry, fp, regs->ra); -while (fp && !(fp &0x3 ) && entry->nr < entry->max_stack) +while (fp && !(fp &0x7 ) && entry->nr < entry->max_stack) fp =user_backtrace (entry, fp,0 ); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 384/634 RDMA/hns: Fix ah error counter in sw stat not increasing
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxian Huang <[email protected]>
[ Upstream commit 39c047d4047a1242aeefa87513174b56a91080ab ]
There are several error cases where hns_roce_create_ah() returns directly without jumping to sw stat path, thus leading to a problem that the ah error counter does not increase.
--- drivers/infiniband/hw/hns/hns_roce_ah.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/infiniband/hw/hns/hns_roce_ah.c +9 -5
@@ -64,8 +64,10 @@ int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,u8 tc_mode =0 ;int ret; -if (hr_dev->pci_dev->revision ==PCI_REVISION_ID_HIP08 && udata) -return -EOPNOTSUPP ; +if (hr_dev->pci_dev->revision ==PCI_REVISION_ID_HIP08 && udata) { + ret = -EOPNOTSUPP ; + goto err_out; + } ah->av.port =rdma_ah_get_port_num (ah_attr); ah->av.gid_index = grh->sgid_index;
@@ -83,7 +85,7 @@ int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr, ret =0 ;if (ret && grh->sgid_attr->gid_type ==IB_GID_TYPE_ROCE_UDP_ENCAP ) -return ret; + goto err_out;if (tc_mode ==HNAE3_TC_MAP_MODE_DSCP && grh->sgid_attr->gid_type ==IB_GID_TYPE_ROCE_UDP_ENCAP )
@@ -91,8 +93,10 @@ int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,else ah->av.sl =rdma_ah_get_sl (ah_attr); -if (!check_sl_valid (hr_dev, ah->av.sl)) -return -EINVAL ; +if (!check_sl_valid (hr_dev, ah->av.sl)) { + ret = -EINVAL ; + goto err_out; + }memcpy (ah->av.dgid, grh->dgid.raw,HNS_ROCE_GID_SIZE );memcpy (ah->av.mac, ah_attr->roce.dmac,ETH_ALEN );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 385/634 RDMA/cxgb4: Added NULL check for lookup_atid
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Lobanov <[email protected]>
[ Upstream commit e766e6a92410ca269161de059fff0843b8ddd65f ]
The lookup_atid() function can return NULL if the ATID is invalid or does not exist in the identifier table, which could lead to dereferencing a null pointer without a check in the act_establish() and act_open_rpl() functions. Add a NULL check to prevent null pointer dereferencing.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/infiniband/hw/cxgb4/cm.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/infiniband/hw/cxgb4/cm.c +5 -0
@@ -1222,6 +1222,8 @@ static int act_establish(struct c4iw_dev *dev, struct sk_buff *skb)int ret; ep =lookup_atid (t, atid); +if (!ep) +return -EINVAL ;pr_debug ("ep %p tid %u snd_isn %u rcv_isn %u\n" , ep, tid,be32_to_cpu (req->snd_isn),be32_to_cpu (req->rcv_isn));
@@ -2279,6 +2281,9 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)int ret =0 ; ep =lookup_atid (t, atid); +if (!ep) +return -EINVAL ; + la = (struct sockaddr_in *)&ep->com.local_addr; ra = (struct sockaddr_in *)&ep->com.remote_addr; la6 = (struct sockaddr_in6 *)&ep->com.local_addr;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 386/634 RDMA/irdma: fix error message in irdma_modify_qp_roce()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vitaliy Shevtsov <[email protected]>
[ Upstream commit 9f0eafe86ea0a589676209d0cff1a1ed49a037d3 ]
Use a correct field max_dest_rd_atomic instead of max_rd_atomic for the error output.
Found by Linux Verification Center (linuxtesting.org) with Svace.
--- drivers/infiniband/hw/irdma/verbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/irdma/verbs.c +1 -1
@@ -1347,7 +1347,7 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,if (attr->max_dest_rd_atomic > dev->hw_attrs.max_hw_ird) {ibdev_err (&iwdev->ibdev,"rd_atomic = %d, above max_hw_ird=%d\n" , - attr->max_rd_atomic, + attr->max_dest_rd_atomic, dev->hw_attrs.max_hw_ird);return -EINVAL ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 387/634 ntb: intel: Fix the NULL vs IS_ERR() bug for debugfs_create_dir()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit e229897d373a87ee09ec5cc4ecd4bb2f895fc16b ]
The debugfs_create_dir() function returns error pointers. It never returns NULL. So use IS_ERR() to check it.
--- drivers/ntb/hw/intel/ntb_hw_gen1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ntb/hw/intel/ntb_hw_gen1.c +1 -1
@@ -778,7 +778,7 @@ static void ndev_init_debugfs(struct intel_ntb_dev *ndev) ndev->debugfs_dir =debugfs_create_dir (pci_name (ndev->ntb.pdev), debugfs_dir); -if (!ndev->debugfs_dir) +if (IS_ERR (ndev->debugfs_dir)) ndev->debugfs_info =NULL ;else ndev->debugfs_info =
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 388/634 ntb_perf: Fix printk format
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Max Hawking <[email protected]>
[ Upstream commit 1501ae7479c8d0f66efdbfdc9ae8d6136cefbd37 ]
The correct printk format is %pa or %pap, but not %pa[p].
--- drivers/ntb/test/ntb_perf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ntb/test/ntb_perf.c +1 -1
@@ -1227,7 +1227,7 @@ static ssize_t perf_dbgfs_read_info(struct file *filep, char __user *ubuf, "\tOut buffer addr 0x%pK\n", peer->outbuf); pos +=scnprintf (buf + pos, buf_size - pos, -"\tOut buff phys addr %pa[p]\n" , &peer->out_phys_addr); +"\tOut buff phys addr %pap\n" , &peer->out_phys_addr); pos +=scnprintf (buf + pos, buf_size - pos,"\tOut buffer size %pa\n" , &peer->outbuf_size);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 389/634 ntb: Force physically contiguous allocation of rx ring buffers
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Jiang <[email protected]>
[ Upstream commit 061a785a114f159e990ea8ed8d1b7dca4b41120f ]
Physical addresses under IOVA on x86 platform are mapped contiguously as a side effect before the patch that removed CONFIG_DMA_REMAP. The NTB rx buffer ring is a single chunk DMA buffer that is allocated against the NTB PCI device. If the receive side is using a DMA device, then the buffers are remapped against the DMA device before being submitted via the dmaengine API. This scheme becomes a problem when the physical memory is discontiguous. When dma_map_page() is called on the kernel virtual address from the dma_alloc_coherent() call, the new IOVA mapping no longer points to all the physical memory allocated due to being discontiguous. Change dma_alloc_coherent() to dma_alloc_attrs() in order to force DMA_ATTR_FORCE_CONTIGUOUS attribute. This is the best fix for the circumstance. A potential future solution may be having the DMA mapping API providing a way to alias an existing IOVA mapping to a new device perhaps.
This fix is not to fix the patch pointed to by the fixes tag, but to fix the issue arised in the ntb_transport driver on x86 platforms after the said patch is applied.
--- drivers/ntb/ntb_transport.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
drivers/ntb/ntb_transport.c +18 -5
@@ -807,16 +807,29 @@ static void ntb_free_mw(struct ntb_transport_ctx *nt, int num_mw) }static int ntb_alloc_mw_buffer (struct ntb_transport_mw *mw, -struct device *dma_dev,size_t align) +struct device *ntb_dev,size_t align) {dma_addr_t dma_addr;void *alloc_addr, *virt_addr;int rc; - alloc_addr =dma_alloc_coherent (dma_dev, mw->alloc_size, - &dma_addr,GFP_KERNEL ); +/* +* The buffer here is allocated against the NTB device. The reason to +* use dma_alloc_*() call is to allocate a large IOVA contiguous buffer +* backing the NTB BAR for the remote host to write to. During receive +* processing, the data is being copied out of the receive buffer to +* the kernel skbuff. When a DMA device is being used, dma_map_page() +* is called on the kvaddr of the receive buffer (from dma_alloc_*()) +* and remapped against the DMA device. It appears to be a double +* DMA mapping of buffers, but first is mapped to the NTB device and +* second is to the DMA device. DMA_ATTR_FORCE_CONTIGUOUS is necessary +* in order for the later dma_map_page() to not fail. +*/ + alloc_addr =dma_alloc_attrs (ntb_dev, mw->alloc_size, + &dma_addr,GFP_KERNEL , +DMA_ATTR_FORCE_CONTIGUOUS );if (!alloc_addr) { -dev_err (dma_dev,"Unable to alloc MW buff of size %zu\n" , +dev_err (ntb_dev,"Unable to alloc MW buff of size %zu\n" , mw->alloc_size);return -ENOMEM ; }
@@ -845,7 +858,7 @@ static int ntb_alloc_mw_buffer(struct ntb_transport_mw *mw,return 0 ; err: -dma_free_coherent (dma_dev, mw->alloc_size, alloc_addr, dma_addr); +dma_free_coherent (ntb_dev, mw->alloc_size, alloc_addr, dma_addr);return rc; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 390/634 nfsd: call cache_put if xdr_reserve_space returns NULL
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guoqing Jiang <[email protected]>
[ Upstream commit d078cbf5c38de83bc31f83c47dcd2184c04a50c7 ]
If not enough buffer space available, but idmap_lookup has triggered lookup_fn which calls cache_get and returns successfully. Then we missed to call cache_put here which pairs with cache_get.
--- fs/nfsd/nfs4idmap.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
fs/nfsd/nfs4idmap.c +9 -4
@@ -581,6 +581,7 @@ static __be32 idmap_id_to_name(struct xdr_stream *xdr, .id = id, .type = type, }; +__be32 status = nfs_ok;__be32 *p;int ret;struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);
@@ -593,12 +594,16 @@ static __be32 idmap_id_to_name(struct xdr_stream *xdr,return nfserrno (ret); ret =strlen (item->name);WARN_ON_ONCE (ret >IDMAP_NAMESZ ); + p =xdr_reserve_space (xdr, ret +4 ); -if (!p) -return nfserr_resource; - p =xdr_encode_opaque (p, item->name, ret); +if (unlikely (!p)) { + status = nfserr_resource; + goto out_put; + } +xdr_encode_opaque (p, item->name, ret); +out_put:cache_put (&item->h, nn->idtoname_cache); -return 0 ; +return status; } static bool
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 391/634 nfsd: return -EINVAL when namelen is 0
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Lingfeng <[email protected]>
[ Upstream commit 22451a16b7ab7debefce660672566be887db1637 ]
When we have a corrupted main.sqlite in /var/lib/nfs/nfsdcld/, it may result in namelen being 0, which will cause memdup_user() to return ZERO_SIZE_PTR.
When we access the name.data that has been assigned the value of ZERO_SIZE_PTR in nfs4_client_to_reclaim(), null pointer dereference is triggered.
[ T1205] ==================================================================
[ T1205] BUG: KASAN: null-ptr-deref in nfs4_client_to_reclaim+0xe9/0x260
[ T1205] Read of size 1 at addr 0000000000000010 by task nfsdcld/1205
[ T1205]
[ T1205] CPU: 11 PID: 1205 Comm: nfsdcld Not tainted 5.10.0-00003-g2c1423731b8d #406
[ T1205] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190727_073836-buildvm-ppc64le-16.ppc.fedoraproject.org-3.fc31 04/01/2014 [ T1205] Call Trace:
[ T1205] dump_stack+0x9a/0xd0 [ T1205] ? nfs4_client_to_reclaim+0xe9/0x260 [ T1205] __kasan_report.cold+0x34/0x84 [ T1205] ? nfs4_client_to_reclaim+0xe9/0x260 [ T1205] kasan_report+0x3a/0x50 [ T1205] nfs4_client_to_reclaim+0xe9/0x260 [ T1205] ? nfsd4_release_lockowner+0x410/0x410 [ T1205] cld_pipe_downcall+0x5ca/0x760 [ T1205] ? nfsd4_cld_tracking_exit+0x1d0/0x1d0 [ T1205] ? down_write_killable_nested+0x170/0x170 [ T1205] ? avc_policy_seqno+0x28/0x40 [ T1205] ? selinux_file_permission+0x1b4/0x1e0 [ T1205] rpc_pipe_write+0x84/0xb0 [ T1205] vfs_write+0x143/0x520 [ T1205] ksys_write+0xc9/0x170 [ T1205] ? __ia32_sys_read+0x50/0x50 [ T1205] ? ktime_get_coarse_real_ts64+0xfe/0x110 [ T1205] ? ktime_get_coarse_real_ts64+0xa2/0x110 [ T1205] do_syscall_64+0x33/0x40 [ T1205] entry_SYSCALL_64_after_hwframe+0x67/0xd1
[ T1205] RIP: 0033:0x7fdbdb761bc7
[ T1205] Code: 0f 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b7 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 514 [ T1205] RSP: 002b:00007fff8c4b7248 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[ T1205] RAX: ffffffffffffffda RBX: 000000000000042b RCX: 00007fdbdb761bc7
[ T1205] RDX: 000000000000042b RSI: 00007fff8c4b75f0 RDI: 0000000000000008
[ T1205] RBP: 00007fdbdb761bb0 R08: 0000000000000000 R09: 0000000000000001
[ T1205] R10: 0000000000000000 R11: 0000000000000246 R12: 000000000000042b
[ T1205] R13: 0000000000000008 R14: 00007fff8c4b75f0 R15: 0000000000000000
[ T1205] ==================================================================
Fix it by checking namelen.
--- fs/nfsd/nfs4recover.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/nfsd/nfs4recover.c +8 -0
@@ -809,6 +809,10 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg, ci = &cmsg->cm_u.cm_clntinfo;if (get_user (namelen, &ci->cc_name.cn_len))return -EFAULT ; +if (!namelen) { +dprintk ("%s: namelen should not be zero" , __func__); +return -EINVAL ; + } name.data =memdup_user (&ci->cc_name.cn_id, namelen);if (IS_ERR (name.data))return PTR_ERR (name.data);
@@ -831,6 +835,10 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg, cnm = &cmsg->cm_u.cm_name;if (get_user (namelen, &cnm->cn_len))return -EFAULT ; +if (!namelen) { +dprintk ("%s: namelen should not be zero" , __func__); +return -EINVAL ; + } name.data =memdup_user (&cnm->cn_id, namelen);if (IS_ERR (name.data))return PTR_ERR (name.data);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 392/634 nfsd: untangle code in nfsd4_deleg_getattr_conflict()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
[ Upstream commit a078a7dc0eaa9db288ae45319f7f7503968af546 ]
The code in nfsd4_deleg_getattr_conflict() is convoluted and buggy.
With this patch we:
- properly handle non-nfsd leases. We must not assume flc_owner is a
delegation unless fl_lmops == &nfsd_lease_mng_ops
- move the main code out of the for loop
- have a single exit which calls nfs4_put_stid() (and other exits which don't need to call that)
[ jlayton: refactored on top of Neil's other patch: nfsd: fix
nfsd4_deleg_getattr_conflict in presence of third party lease ]
--- fs/nfsd/nfs4state.c | 131 +++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 69 deletions(-)
fs/nfsd/nfs4state.c +62 -69
@@ -8836,6 +8836,7 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry,__be32 status;struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);struct file_lock_context *ctx; +struct nfs4_delegation *dp =NULL ;struct file_lease *fl;struct iattr attrs;struct nfs4_cb_fattr *ncf;
@@ -8845,84 +8846,76 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry, ctx =locks_inode_context (inode);if (!ctx)return 0 ; + +#define NON_NFSD_LEASE ((void *)1) +spin_lock (&ctx->flc_lock);for_each_file_lock (fl, &ctx->flc_lease) { -unsigned char type = fl->c.flc_type; -if (fl->c.flc_flags ==FL_LAYOUT )continue ; -if (fl->fl_lmops != &nfsd_lease_mng_ops) { -/* -* non-nfs lease, if it's a lease with F_RDLCK then -* we are done; there isn't any write delegation -* on this inode -*/ -if (type ==F_RDLCK ) -break ; - -nfsd_stats_wdeleg_getattr_inc (nn); -spin_unlock (&ctx->flc_lock); - - status =nfserrno (nfsd_open_break_lease (inode,NFSD_MAY_READ )); +if (fl->c.flc_type ==F_WRLCK ) { +if (fl->fl_lmops == &nfsd_lease_mng_ops) + dp = fl->c.flc_owner; +else + dp =NON_NFSD_LEASE ; + } +break ; + } +if (dp ==NULL || dp ==NON_NFSD_LEASE || + dp->dl_recall.cb_clp == *(rqstp->rq_lease_breaker)) { +spin_unlock (&ctx->flc_lock); +if (dp ==NON_NFSD_LEASE ) { + status =nfserrno (nfsd_open_break_lease (inode, +NFSD_MAY_READ ));if (status != nfserr_jukebox || !nfsd_wait_for_delegreturn (rqstp, inode))return status; -return 0 ; } -if (type ==F_WRLCK ) { -struct nfs4_delegation *dp = fl->c.flc_owner; +return 0 ; + } -if (dp->dl_recall.cb_clp == *(rqstp->rq_lease_breaker)) { -spin_unlock (&ctx->flc_lock); -return 0 ; - } -nfsd_stats_wdeleg_getattr_inc (nn); - dp = fl->c.flc_owner; -refcount_inc (&dp->dl_stid.sc_count); - ncf = &dp->dl_cb_fattr; -nfs4_cb_getattr (&dp->dl_cb_fattr); -spin_unlock (&ctx->flc_lock); -wait_on_bit_timeout (&ncf->ncf_cb_flags,CB_GETATTR_BUSY , -TASK_INTERRUPTIBLE ,NFSD_CB_GETATTR_TIMEOUT ); -if (ncf->ncf_cb_status) { -/* Recall delegation only if client didn't respond */ - status =nfserrno (nfsd_open_break_lease (inode,NFSD_MAY_READ )); -if (status != nfserr_jukebox || - !nfsd_wait_for_delegreturn (rqstp, inode)) { -nfs4_put_stid (&dp->dl_stid); -return status; - } - } -if (!ncf->ncf_file_modified && - (ncf->ncf_initial_cinfo != ncf->ncf_cb_change || - ncf->ncf_cur_fsize != ncf->ncf_cb_fsize)) - ncf->ncf_file_modified = true; -if (ncf->ncf_file_modified) { -int err; - -/* -* Per section 10.4.3 of RFC 8881, the server would -* not update the file's metadata with the client's -* modified size -*/ - attrs.ia_mtime = attrs.ia_ctime =current_time (inode); - attrs.ia_valid =ATTR_MTIME |ATTR_CTIME |ATTR_DELEG ; -inode_lock (inode); - err =notify_change (&nop_mnt_idmap, dentry, &attrs,NULL ); -inode_unlock (inode); -if (err) { -nfs4_put_stid (&dp->dl_stid); -return nfserrno (err); - } - ncf->ncf_cur_fsize = ncf->ncf_cb_fsize; - *size = ncf->ncf_cur_fsize; - *modified = true; - } -nfs4_put_stid (&dp->dl_stid); -return 0 ; +nfsd_stats_wdeleg_getattr_inc (nn); +refcount_inc (&dp->dl_stid.sc_count); + ncf = &dp->dl_cb_fattr; +nfs4_cb_getattr (&dp->dl_cb_fattr); +spin_unlock (&ctx->flc_lock); + +wait_on_bit_timeout (&ncf->ncf_cb_flags,CB_GETATTR_BUSY , +TASK_INTERRUPTIBLE ,NFSD_CB_GETATTR_TIMEOUT ); +if (ncf->ncf_cb_status) { +/* Recall delegation only if client didn't respond */ + status =nfserrno (nfsd_open_break_lease (inode,NFSD_MAY_READ )); +if (status != nfserr_jukebox || + !nfsd_wait_for_delegreturn (rqstp, inode)) + goto out_status; + } +if (!ncf->ncf_file_modified && + (ncf->ncf_initial_cinfo != ncf->ncf_cb_change || + ncf->ncf_cur_fsize != ncf->ncf_cb_fsize)) + ncf->ncf_file_modified = true; +if (ncf->ncf_file_modified) { +int err; + +/* +* Per section 10.4.3 of RFC 8881, the server would +* not update the file's metadata with the client's +* modified size +*/ + attrs.ia_mtime = attrs.ia_ctime =current_time (inode); + attrs.ia_valid =ATTR_MTIME |ATTR_CTIME |ATTR_DELEG ; +inode_lock (inode); + err =notify_change (&nop_mnt_idmap, dentry, &attrs,NULL ); +inode_unlock (inode); +if (err) { + status =nfserrno (err); + goto out_status; } -break ; + ncf->ncf_cur_fsize = ncf->ncf_cb_fsize; + *size = ncf->ncf_cur_fsize; + *modified = true; } -spin_unlock (&ctx->flc_lock); -return 0 ; + status =0 ; +out_status: +nfs4_put_stid (&dp->dl_stid); +return status; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 393/634 nfsd: fix initial getattr on write delegation
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
[ Upstream commit bf92e5008b17f935a6de8b708551e02c2294121c ]
At this point in compound processing, currentfh refers to the parent of the file, not the file itself. Get the correct dentry from the delegation stateid instead.
--- fs/nfsd/nfs4state.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-)
fs/nfsd/nfs4state.c +25 -8
@@ -5912,6 +5912,28 @@ static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status) } } +static bool +nfs4_delegation_stat (struct nfs4_delegation *dp,struct svc_fh *currentfh, +struct kstat *stat) +{ +struct nfsd_file *nf =find_rw_file (dp->dl_stid.sc_file); +struct path path; +int rc; + +if (!nf) +return false; + + path.mnt = currentfh->fh_export->ex_path.mnt; + path.dentry =file_dentry (nf->nf_file); + + rc =vfs_getattr (&path, stat, + (STATX_SIZE |STATX_CTIME |STATX_CHANGE_COOKIE ), +AT_STATX_SYNC_AS_STAT ); + +nfsd_file_put (nf); +return rc ==0 ; +} +/* * The Linux NFS server does not offer write delegations to NFSv4.0 * clients in order to avoid conflicts between write delegations and
@@ -5947,7 +5969,6 @@ nfs4_open_delegation(struct nfsd4_open *open, struct nfs4_ol_stateid *stp,int cb_up;int status =0 ;struct kstat stat; -struct path path; cb_up =nfsd4_cb_channel_good (oo->oo_owner.so_client); open->op_recall = false;
@@ -5983,20 +6004,16 @@ nfs4_open_delegation(struct nfsd4_open *open, struct nfs4_ol_stateid *stp,memcpy (&open->op_delegate_stateid, &dp->dl_stid.sc_stateid,sizeof (dp->dl_stid.sc_stateid));if (open->op_share_access &NFS4_SHARE_ACCESS_WRITE ) { - open->op_delegate_type =NFS4_OPEN_DELEGATE_WRITE ; -trace_nfsd_deleg_write (&dp->dl_stid.sc_stateid); - path.mnt = currentfh->fh_export->ex_path.mnt; - path.dentry = currentfh->fh_dentry; -if (vfs_getattr (&path, &stat, - (STATX_SIZE |STATX_CTIME |STATX_CHANGE_COOKIE ), -AT_STATX_SYNC_AS_STAT )) { +if (!nfs4_delegation_stat (dp, currentfh, &stat)) {nfs4_put_stid (&dp->dl_stid);destroy_delegation (dp); goto out_no_deleg; } + open->op_delegate_type =NFS4_OPEN_DELEGATE_WRITE ; dp->dl_cb_fattr.ncf_cur_fsize = stat.size; dp->dl_cb_fattr.ncf_initial_cinfo =nfsd4_change_attribute (&stat,d_inode (currentfh->fh_dentry)); +trace_nfsd_deleg_write (&dp->dl_stid.sc_stateid); }else { open->op_delegate_type =NFS4_OPEN_DELEGATE_READ ;trace_nfsd_deleg_read (&dp->dl_stid.sc_stateid);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 394/634 crypto: caam - Pad SG length when allocating hash edesc
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
[ Upstream commit 5124bc96162667766f6120b19f57a640c2eccb2a ]
Because hardware will read in multiples of 4 SG entries, ensure the allocated length is always padded. This was already done by some callers of ahash_edesc_alloc, but ahash_digest was conspicuously missing.
In any case, doing it in the allocation function ensures that the memory is always there.
--- drivers/crypto/caam/caamhash.c | 1 + 1 file changed, 1 insertion(+)
drivers/crypto/caam/caamhash.c +1 -0
@@ -708,6 +708,7 @@ static struct ahash_edesc *ahash_edesc_alloc(struct ahash_request *req, GFP_KERNEL :GFP_ATOMIC ;struct ahash_edesc *edesc; + sg_num =pad_sg_nents (sg_num); edesc =kzalloc (struct_size (edesc, sec4_sg, sg_num), flags);if (!edesc)return NULL ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 395/634 crypto: powerpc/p10-aes-gcm - Disable CRYPTO_AES_GCM_P10
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danny Tsen <[email protected]>
[ Upstream commit 44ac4625ea002deecd0c227336c95b724206c698 ]
Data mismatch found when testing ipsec tunnel with AES/GCM crypto. Disabling CRYPTO_AES_GCM_P10 in Kconfig for this feature.
--- arch/powerpc/crypto/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/crypto/Kconfig +1 -0
@@ -96,6 +96,7 @@ config CRYPTO_AES_PPC_SPE config CRYPTO_AES_GCM_P10 tristate "Stitched AES/GCM acceleration support on P10 or later CPU (PPC)" + depends on BROKEN depends on PPC64 && CPU_LITTLE_ENDIAN && VSX select CRYPTO_LIB_AES select CRYPTO_ALGAPI
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 396/634 f2fs: atomic: fix to avoid racing w/ GC
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit 1a0bd289a5db1df8df8fab949633a0b8d3f235ee ]
Case #1:
SQLite App GC Thread Kworker Shrinker
- f2fs_ioc_start_atomic_write
- f2fs_ioc_commit_atomic_write
- f2fs_commit_atomic_write
- filemap_write_and_wait_range
: write atomic_file's data to cow_inode
echo 3 > drop_caches to drop atomic_file's cache.
- f2fs_gc
- gc_data_segment
- move_data_page
- set_page_dirty
- writepages
- f2fs_do_write_data_page : overwrite atomic_file's data to cow_inode
- f2fs_down_write(&fi->i_gc_rwsem[WRITE])
- __f2fs_commit_atomic_write
- f2fs_up_write(&fi->i_gc_rwsem[WRITE])
Case #2:
SQLite App GC Thread Kworker
- f2fs_ioc_start_atomic_write
- __writeback_single_inode
- do_writepages
- f2fs_write_cache_pages
- f2fs_write_single_data_page
- f2fs_do_write_data_page : write atomic_file's data to cow_inode
- f2fs_gc
- gc_data_segment
- move_data_page
- set_page_dirty
- writepages
- f2fs_do_write_data_page
: overwrite atomic_file's data to cow_inode
- f2fs_ioc_commit_atomic_write
In above cases racing in between atomic_write and GC, previous data in atomic_file may be overwrited to cow_file, result in data corruption.
This patch introduces PAGE_PRIVATE_ATOMIC_WRITE bit flag in page.private, and use it to indicate that there is last dirty data in atomic file, and the data should be writebacked into cow_file, if the flag is not tagged in page, we should never write data across files.
--- fs/f2fs/data.c | 10 +++++++++- fs/f2fs/f2fs.h | 8 +++++++- 2 files changed, 16 insertions(+), 2 deletions(-)
fs/f2fs/data.c +9 -1
@@ -2645,10 +2645,13 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)struct dnode_of_data dn;struct node_info ni;bool ipu_force = false; +bool atomic_commit;int err =0 ;/* Use COW inode to make dnode_of_data for atomic write */ -if (f2fs_is_atomic_file (inode)) + atomic_commit =f2fs_is_atomic_file (inode) && +page_private_atomic (fio->page); +if (atomic_commit)set_new_dnode (&dn,F2FS_I (inode)->cow_inode,NULL ,NULL ,0 );else set_new_dnode (&dn, inode,NULL ,NULL ,0 );
@@ -2747,6 +2750,8 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)f2fs_outplace_write_data (&dn, fio);trace_f2fs_do_write_data_page (page_folio (page),OPU );set_inode_flag (inode,FI_APPEND_WRITE ); +if (atomic_commit) +clear_page_private_atomic (page); out_writepage:f2fs_put_dnode (&dn); out:
@@ -3716,6 +3721,9 @@ static int f2fs_write_end(struct file *file,set_page_dirty (page); +if (f2fs_is_atomic_file (inode)) +set_page_private_atomic (page); +if (pos + copied >i_size_read (inode) && !f2fs_verity_in_progress (inode)) {f2fs_i_size_write (inode, pos + copied);
fs/f2fs/f2fs.h +7 -1
@@ -1418,7 +1418,8 @@ static inline void f2fs_clear_bit(unsigned int nr, char *addr);* bit 1 PAGE_PRIVATE_ONGOING_MIGRATION * bit 2 PAGE_PRIVATE_INLINE_INODE * bit 3 PAGE_PRIVATE_REF_RESOURCE -* bit 4- f2fs private data +* bit 4 PAGE_PRIVATE_ATOMIC_WRITE +* bit 5- f2fs private data * * Layout B: lowest bit should be 0 * page.private is a wrapped pointer.
@@ -1428,6 +1429,7 @@ enum {PAGE_PRIVATE_ONGOING_MIGRATION ,/* data page which is on-going migrating */ PAGE_PRIVATE_INLINE_INODE ,/* inode page contains inline data */ PAGE_PRIVATE_REF_RESOURCE ,/* dirty page has referenced resources */ +PAGE_PRIVATE_ATOMIC_WRITE ,/* data page from atomic write path */ PAGE_PRIVATE_MAX };
@@ -2396,14 +2398,17 @@ static inline void clear_page_private_##name(struct page *page) \PAGE_PRIVATE_GET_FUNC (nonpointer,NOT_POINTER );PAGE_PRIVATE_GET_FUNC (inline,INLINE_INODE );PAGE_PRIVATE_GET_FUNC (gcing,ONGOING_MIGRATION ); +PAGE_PRIVATE_GET_FUNC (atomic,ATOMIC_WRITE );PAGE_PRIVATE_SET_FUNC (reference,REF_RESOURCE );PAGE_PRIVATE_SET_FUNC (inline,INLINE_INODE );PAGE_PRIVATE_SET_FUNC (gcing,ONGOING_MIGRATION ); +PAGE_PRIVATE_SET_FUNC (atomic,ATOMIC_WRITE );PAGE_PRIVATE_CLEAR_FUNC (reference,REF_RESOURCE );PAGE_PRIVATE_CLEAR_FUNC (inline,INLINE_INODE );PAGE_PRIVATE_CLEAR_FUNC (gcing,ONGOING_MIGRATION ); +PAGE_PRIVATE_CLEAR_FUNC (atomic,ATOMIC_WRITE );static inline unsigned long get_page_private_data (struct page *page) {
@@ -2435,6 +2440,7 @@ static inline void clear_page_private_all(struct page *page)clear_page_private_reference (page);clear_page_private_gcing (page);clear_page_private_inline (page); +clear_page_private_atomic (page);f2fs_bug_on (F2FS_P_SB (page),page_private (page)); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 397/634 f2fs: reduce expensive checkpoint trigger frequency
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit aaf8c0b9ae042494cb4585883b15c1332de77840 ]
We may trigger high frequent checkpoint for below case:
1. mkdir /mnt/dir1; set dir1 encrypted
2. touch /mnt/file1; fsync /mnt/file1
3. mkdir /mnt/dir2; set dir2 encrypted
4. touch /mnt/file2; fsync /mnt/file2
...
Although, newly created dir and file are not related, due to commit bbf156f7afa7 ("f2fs: fix lost xattrs of directories"), we will trigger checkpoint whenever fsync() comes after a new encrypted dir created.
In order to avoid such performance regression issue, let's record an entry including directory's ino in global cache whenever we update directory's xattr data, and then triggerring checkpoint() only if xattr metadata of target file's parent was updated.
This patch updates to cover below no encryption case as well:
1) parent is checkpointed
2) set_xattr(dir) w/ new xnid
3) create(file)
4) fsync(file)
--- fs/f2fs/f2fs.h | 2 ++ fs/f2fs/file.c | 3 +++ fs/f2fs/xattr.c | 14 ++++++++++++-- include/trace/events/f2fs.h | 3 ++- 4 files changed, 19 insertions(+), 3 deletions(-)
fs/f2fs/f2fs.h +2 -0
@@ -285,6 +285,7 @@ enum {APPEND_INO ,/* for append ino list */ UPDATE_INO ,/* for update ino list */ TRANS_DIR_INO ,/* for transactions dir ino list */ +XATTR_DIR_INO ,/* for xattr updated dir ino list */ FLUSH_INO ,/* for multiple device flushing */ MAX_INO_ENTRY, /* max. list */ };
@@ -1155,6 +1156,7 @@ enum cp_reason_type {CP_FASTBOOT_MODE ,CP_SPEC_LOG_NUM ,CP_RECOVER_DIR , + CP_XATTR_DIR, }; enum iostat_type {
fs/f2fs/file.c +3 -0
@@ -218,6 +218,9 @@ static inline enum cp_reason_type need_do_checkpoint(struct inode *inode) f2fs_exist_written_data(sbi, F2FS_I(inode)->i_pino, TRANS_DIR_INO)) cp_reason =CP_RECOVER_DIR ; + else if (f2fs_exist_written_data(sbi, F2FS_I(inode)->i_pino, +XATTR_DIR_INO )) + cp_reason =CP_XATTR_DIR ;return cp_reason; }
fs/f2fs/xattr.c +12 -2
@@ -629,6 +629,7 @@ static int __f2fs_setxattr(struct inode *inode, int index, const char *name, const void *value, size_t size, struct page *ipage, int flags) { + struct f2fs_sb_info *sbi = F2FS_I_SB(inode);struct f2fs_xattr_entry *here, *last;void *base_addr, *last_base_addr;int found, newsize;
@@ -772,9 +773,18 @@ static int __f2fs_setxattr(struct inode *inode, int index,if (index ==F2FS_XATTR_INDEX_ENCRYPTION && !strcmp (name,F2FS_XATTR_NAME_ENCRYPTION_CONTEXT ))f2fs_set_encrypted_inode (inode); -if (S_ISDIR (inode->i_mode)) -set_sbi_flag (F2FS_I_SB (inode),SBI_NEED_CP ); +if (!S_ISDIR (inode->i_mode)) + goto same; +/* +* In restrict mode, fsync() always try to trigger checkpoint for all +* metadata consistency, in other mode, it triggers checkpoint when +* parent's xattr metadata was updated. +*/ +if (F2FS_OPTION (sbi).fsync_mode ==FSYNC_MODE_STRICT ) +set_sbi_flag (sbi,SBI_NEED_CP ); +else +f2fs_add_ino_entry (sbi, inode->i_ino,XATTR_DIR_INO ); same:if (is_inode_flag_set (inode,FI_ACL_MODE )) { inode->i_mode =F2FS_I (inode)->i_acl_mode;
include/trace/events/f2fs.h +2 -1
@@ -139,7 +139,8 @@ TRACE_DEFINE_ENUM(EX_BLOCK_AGE); { CP_NODE_NEED_CP, "node needs cp" }, \ { CP_FASTBOOT_MODE, "fastboot mode" }, \ { CP_SPEC_LOG_NUM, "log type is 2" }, \ - { CP_RECOVER_DIR, "dir needs recovery" }) + { CP_RECOVER_DIR, "dir needs recovery" }, \ + { CP_XATTR_DIR, "dir's xattr updated" }) #define show_shutdown_mode(type) \ __print_symbolic(type, \
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 398/634 f2fs: fix to avoid racing in between read and OPU dio write
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit 0cac51185e65dc2a20686184e02f3cafc99eb202 ]
If lfs mode is on, buffered read may race w/ OPU dio write as below, it may cause buffered read hits unwritten data unexpectly, and for dio read, the race condition exists as well.
Thread A Thread B
- f2fs_file_write_iter
- f2fs_dio_write_iter
- __iomap_dio_rw
- f2fs_iomap_begin
- f2fs_map_blocks
- __allocate_data_block
- allocated blkaddr #x
- iomap_dio_submit_bio
- f2fs_file_read_iter
- filemap_read
- f2fs_read_data_folio
- f2fs_mpage_readpages
- f2fs_map_blocks
: get blkaddr #x
- f2fs_submit_read_bio
IRQ
- f2fs_read_end_io
: read IO on blkaddr #x complete
IRQ
- iomap_dio_bio_end_io
: direct write IO on blkaddr #x complete
In LFS mode, if there is inflight dio, let's wait for its completion, this policy won't cover all race cases, however it is a tradeoff which avoids abusing lock around IO paths.
--- fs/f2fs/file.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/f2fs/file.c +4 -0
@@ -4590,6 +4590,10 @@ static ssize_t f2fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)f2fs_trace_rw_file_path (iocb->ki_filp, iocb->ki_pos,iov_iter_count (to),READ ); +/* In LFS mode, if there is inflight dio, wait for its completion */ +if (f2fs_lfs_mode (F2FS_I_SB (inode))) +inode_dio_wait (inode); +if (f2fs_should_use_dio (inode, iocb, to)) { ret =f2fs_dio_read_iter (iocb, to); }else {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 399/634 f2fs: Create COW inode from parent dentry for atomic write
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yeongjin Gil <[email protected]>
[ Upstream commit 8c1b787938fd86bab27a1492fa887408c75fec2b ]
The i_pino in f2fs_inode_info has the previous parent's i_ino when inode was renamed, which may cause f2fs_ioc_start_atomic_write to fail. If file_wrong_pino is true and i_nlink is 1, then to find a valid pino, we should refer to the dentry from inode.
To resolve this issue, let's get parent inode using parent dentry directly.
--- fs/f2fs/file.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-)
fs/f2fs/file.c +3 -9
@@ -2120,7 +2120,6 @@ static int f2fs_ioc_start_atomic_write(struct file *filp, bool truncate)struct mnt_idmap *idmap =file_mnt_idmap (filp);struct f2fs_inode_info *fi =F2FS_I (inode);struct f2fs_sb_info *sbi =F2FS_I_SB (inode); -struct inode *pinode;loff_t isize;int ret;
@@ -2170,15 +2169,10 @@ static int f2fs_ioc_start_atomic_write(struct file *filp, bool truncate)/* Check if the inode already has a COW inode */ if (fi->cow_inode ==NULL ) {/* Create a COW inode for atomic write */ - pinode =f2fs_iget (inode->i_sb, fi->i_pino); -if (IS_ERR (pinode)) { -f2fs_up_write (&fi->i_gc_rwsem[WRITE ]); - ret =PTR_ERR (pinode); - goto out; - } +struct dentry *dentry =file_dentry (filp); +struct inode *dir =d_inode (dentry->d_parent); - ret =f2fs_get_tmpfile (idmap, pinode, &fi->cow_inode); -iput (pinode); + ret =f2fs_get_tmpfile (idmap, dir, &fi->cow_inode);if (ret) {f2fs_up_write (&fi->i_gc_rwsem[WRITE ]); goto out;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 400/634 f2fs: fix to wait page writeback before setting gcing flag
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit a4d7f2b3238fd5f76b9e6434a0bd5d2e29049cff ]
Soft IRQ Thread
- f2fs_write_end_io
- f2fs_defragment_range
- set_page_private_gcing
- type = WB_DATA_TYPE(page, false);
: assign type w/ F2FS_WB_CP_DATA
due to page_private_gcing() is true
- dec_page_count() w/ wrong type
- end_page_writeback()
Value of F2FS_WB_CP_DATA reference count may become negative under above race condition, the root cause is we missed to wait page writeback before setting gcing page private flag, let's fix it.
--- fs/f2fs/file.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/f2fs/file.c +4 -0
@@ -2791,6 +2791,8 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, goto clear_out; } +f2fs_wait_on_page_writeback (page,DATA , true, true); +set_page_dirty (page);set_page_private_gcing (page);f2fs_put_page (page,1 );
@@ -4184,6 +4186,8 @@ static int redirty_blocks(struct inode *inode, pgoff_t page_idx, int len)/* It will never fail, when page has pinned above */ f2fs_bug_on (F2FS_I_SB (inode), !page); +f2fs_wait_on_page_writeback (page,DATA , true, true); +set_page_dirty (page);set_page_private_gcing (page);f2fs_put_page (page,1 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 401/634 f2fs: atomic: fix to truncate pagecache before on-disk metadata truncation
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit ebd3309aec6271c4616573b0cb83ea25e623070a ]
We should always truncate pagecache while truncating on-disk data.
--- fs/f2fs/file.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/f2fs/file.c +4 -0
@@ -2185,6 +2185,10 @@ static int f2fs_ioc_start_atomic_write(struct file *filp, bool truncate)F2FS_I (fi->cow_inode)->atomic_inode = inode; }else {/* Reuse the already created COW inode */ +f2fs_bug_on (sbi,get_dirty_pages (fi->cow_inode)); + +invalidate_mapping_pages (fi->cow_inode->i_mapping,0 ,-1 ); + ret =f2fs_do_truncate_blocks (fi->cow_inode,0 , true);if (ret) {f2fs_up_write (&fi->i_gc_rwsem[WRITE ]);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 402/634 f2fs: fix to avoid use-after-free in f2fs_stop_gc_thread()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit c7f114d864ac91515bb07ac271e9824a20f5ed95 ]
syzbot reports a f2fs bug as below:
__dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:114 print_report+0xe8/0x550 mm/kasan/report.c:491 kasan_report+0x143/0x180 mm/kasan/report.c:601 kasan_check_range+0x282/0x290 mm/kasan/generic.c:189 instrument_atomic_read_write include/linux/instrumented.h:96 [inline] atomic_fetch_add_relaxed include/linux/atomic/atomic-instrumented.h:252 [inline] __refcount_add include/linux/refcount.h:184 [inline] __refcount_inc include/linux/refcount.h:241 [inline] refcount_inc include/linux/refcount.h:258 [inline] get_task_struct include/linux/sched/task.h:118 [inline] kthread_stop+0xca/0x630 kernel/kthread.c:704 f2fs_stop_gc_thread+0x65/0xb0 fs/f2fs/gc.c:210 f2fs_do_shutdown+0x192/0x540 fs/f2fs/file.c:2283 f2fs_ioc_shutdown fs/f2fs/file.c:2325 [inline] __f2fs_ioctl+0x443a/0xbe60 fs/f2fs/file.c:4325 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
The root cause is below race condition, it may cause use-after-free issue in sbi->gc_th pointer.
- remount
- f2fs_remount
- f2fs_stop_gc_thread
- kfree(gc_th)
- f2fs_ioc_shutdown
- f2fs_do_shutdown
- f2fs_stop_gc_thread
- kthread_stop(gc_th->f2fs_gc_task)
: sbi->gc_thread = NULL;
We will call f2fs_do_shutdown() in two paths:
- for f2fs_ioc_shutdown() path, we should grab sb->s_umount semaphore for fixing.
- for f2fs_shutdown() path, it's safe since caller has already grabbed sb->s_umount semaphore.
--- fs/f2fs/f2fs.h | 2 +- fs/f2fs/file.c | 11 +++++++++-- fs/f2fs/super.c | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-)
fs/f2fs/f2fs.h +1 -1
@@ -3509,7 +3509,7 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,int f2fs_truncate_hole (struct inode *inode,pgoff_t pg_start,pgoff_t pg_end);void f2fs_truncate_data_blocks_range (struct dnode_of_data *dn,int count);int f2fs_do_shutdown (struct f2fs_sb_info *sbi,unsigned int flag, -bool readonly); +bool readonly,bool need_lock);int f2fs_precache_extents (struct inode *inode);int f2fs_fileattr_get (struct dentry *dentry,struct fileattr *fa); int f2fs_fileattr_set(struct mnt_idmap *idmap,
fs/f2fs/file.c +9 -2
@@ -2281,7 +2281,7 @@ static int f2fs_ioc_abort_atomic_write(struct file *filp) }int f2fs_do_shutdown (struct f2fs_sb_info *sbi,unsigned int flag, -bool readonly) +bool readonly,bool need_lock) {struct super_block *sb = sbi->sb;int ret =0 ;
@@ -2328,12 +2328,19 @@ int f2fs_do_shutdown(struct f2fs_sb_info *sbi, unsigned int flag,if (readonly) goto out; +/* grab sb->s_umount to avoid racing w/ remount() */ +if (need_lock) +down_read (&sbi->sb->s_umount); +f2fs_stop_gc_thread (sbi);f2fs_stop_discard_thread (sbi);f2fs_drop_discard_cmd (sbi);clear_opt (sbi,DISCARD ); +if (need_lock) +up_read (&sbi->sb->s_umount); +f2fs_update_time (sbi,REQ_TIME ); out:
@@ -2370,7 +2377,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg) } } - ret =f2fs_do_shutdown (sbi, in, readonly); + ret =f2fs_do_shutdown (sbi, in, readonly, true);if (need_drop)mnt_drop_write_file (filp);
fs/f2fs/super.c +1 -1
@@ -2571,7 +2571,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)static void f2fs_shutdown (struct super_block *sb) { -f2fs_do_shutdown (F2FS_SB (sb),F2FS_GOING_DOWN_NOSYNC , false); +f2fs_do_shutdown (F2FS_SB (sb),F2FS_GOING_DOWN_NOSYNC , false, false); }#ifdef CONFIG_QUOTA
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 403/634 f2fs: compress: dont redirty sparse cluster during {,de}compress
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yeongjin Gil <[email protected]>
[ Upstream commit f785cec298c95d00058560c0715233294a04b8f3 ]
In f2fs_do_write_data_page, when the data block is NULL_ADDR, it skips writepage considering that it has been already truncated. This results in an infinite loop as the PAGECACHE_TAG_TOWRITE tag is not cleared during the writeback process for a compressed file including NULL_ADDR in compress_mode=user.
This is the reproduction process:
1. dd if=/dev/zero bs=4096 count=1024 seek=1024 of=testfile
2. f2fs_io compress testfile
3. dd if=/dev/zero bs=4096 count=1 conv=notrunc of=testfile
4. f2fs_io decompress testfile
To prevent the problem, let's check whether the cluster is fully allocated before redirty its pages.
--- fs/f2fs/compress.c | 36 ++++++++++++++++++++++++++++-------- fs/f2fs/f2fs.h | 12 ++++++++++++ fs/f2fs/file.c | 39 +++++++++++++++++++++------------------ 3 files changed, 61 insertions(+), 26 deletions(-)
fs/f2fs/compress.c +28 -8
@@ -945,7 +945,7 @@ static int __f2fs_get_cluster_blocks(struct inode *inode,unsigned int cluster_size =F2FS_I (inode)->i_cluster_size;int count, i; -for (i =1 , count =1 ; i < cluster_size; i++) { +for (i =0 , count =0 ; i < cluster_size; i++) {block_t blkaddr =data_blkaddr (dn->inode, dn->node_page, dn->ofs_in_node + i);
@@ -956,8 +956,8 @@ static int __f2fs_get_cluster_blocks(struct inode *inode,return count; } -static int __f2fs_cluster_blocks (struct inode *inode, -unsigned int cluster_idx,bool compr_blks) +static int __f2fs_cluster_blocks (struct inode *inode,unsigned int cluster_idx, +enum cluster_check_type type) {struct dnode_of_data dn; unsigned int start_idx = cluster_idx <<
@@ -978,10 +978,12 @@ static int __f2fs_cluster_blocks(struct inode *inode, }if (dn.data_blkaddr ==COMPRESS_ADDR ) { -if (compr_blks) - ret =__f2fs_get_cluster_blocks (inode, &dn); -else +if (type ==CLUSTER_COMPR_BLKS ) + ret =1 +__f2fs_get_cluster_blocks (inode, &dn); +else if (type ==CLUSTER_IS_COMPR ) ret =1 ; + }else if (type ==CLUSTER_RAW_BLKS ) { + ret =__f2fs_get_cluster_blocks (inode, &dn); } fail:f2fs_put_dnode (&dn);
@@ -991,7 +993,16 @@ static int __f2fs_cluster_blocks(struct inode *inode,/* return # of compressed blocks in compressed cluster */ static int f2fs_compressed_blocks (struct compress_ctx *cc) { -return __f2fs_cluster_blocks (cc->inode, cc->cluster_idx, true); +return __f2fs_cluster_blocks (cc->inode, cc->cluster_idx, +CLUSTER_COMPR_BLKS ); +} + +/* return # of raw blocks in non-compressed cluster */ +static int f2fs_decompressed_blocks (struct inode *inode, +unsigned int cluster_idx) +{ +return __f2fs_cluster_blocks (inode, cluster_idx, +CLUSTER_RAW_BLKS ); }/* return whether cluster is compressed one or not */
@@ -999,7 +1010,16 @@ int f2fs_is_compressed_cluster(struct inode *inode, pgoff_t index) {return __f2fs_cluster_blocks (inode, index >>F2FS_I (inode)->i_log_cluster_size, - false); +CLUSTER_IS_COMPR ); +} + +/* return whether cluster contains non raw blocks or not */ +bool f2fs_is_sparse_cluster (struct inode *inode,pgoff_t index) +{ +unsigned int cluster_idx = index >>F2FS_I (inode)->i_log_cluster_size; + +return f2fs_decompressed_blocks (inode, cluster_idx) != +F2FS_I (inode)->i_cluster_size; }static bool cluster_may_compress (struct compress_ctx *cc)
fs/f2fs/f2fs.h +12 -0
@@ -4288,6 +4288,11 @@ static inline bool f2fs_meta_inode_gc_required(struct inode *inode)* compress.c */ #ifdef CONFIG_F2FS_FS_COMPRESSION +enum cluster_check_type { +CLUSTER_IS_COMPR ,/* check only if compressed cluster */ +CLUSTER_COMPR_BLKS ,/* return # of compressed blocks in a cluster */ +CLUSTER_RAW_BLKS /* return # of raw blocks in a cluster */ +};bool f2fs_is_compressed_page (struct page *page);struct page *f2fs_compress_control_page (struct page *page); int f2fs_prepare_compress_overwrite(struct inode *inode,
@@ -4314,6 +4319,7 @@ int f2fs_write_multi_pages(struct compress_ctx *cc,struct writeback_control *wbc, enum iostat_type io_type);int f2fs_is_compressed_cluster (struct inode *inode,pgoff_t index); +bool f2fs_is_sparse_cluster (struct inode *inode,pgoff_t index);void f2fs_update_read_extent_tree_range_compressed (struct inode *inode,pgoff_t fofs,block_t blkaddr,unsigned int llen,unsigned int c_len);
@@ -4400,6 +4406,12 @@ static inline bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi,static inline void f2fs_invalidate_compress_pages (struct f2fs_sb_info *sbi,nid_t ino) { }#define inc_compr_inode_stat (inode) do { } while (0) +static inline int f2fs_is_compressed_cluster ( +struct inode *inode, +pgoff_t index) {return 0 ; } +static inline bool f2fs_is_sparse_cluster ( +struct inode *inode, +pgoff_t index) {return true; } static inline void f2fs_update_read_extent_tree_range_compressed( struct inode *inode, pgoff_t fofs, block_t blkaddr,
fs/f2fs/file.c +21 -18
@@ -4213,9 +4213,8 @@ static int f2fs_ioc_decompress_file(struct file *filp)struct inode *inode =file_inode (filp);struct f2fs_sb_info *sbi =F2FS_I_SB (inode);struct f2fs_inode_info *fi =F2FS_I (inode); -pgoff_t page_idx =0 , last_idx; -int cluster_size = fi->i_cluster_size; -int count, ret; +pgoff_t page_idx =0 , last_idx, cluster_idx; +int ret;if (!f2fs_sb_has_compression (sbi) ||F2FS_OPTION (sbi).compress_mode !=COMPR_MODE_USER )
@@ -4248,10 +4247,15 @@ static int f2fs_ioc_decompress_file(struct file *filp) goto out; last_idx =DIV_ROUND_UP (i_size_read (inode),PAGE_SIZE ); + last_idx >>= fi->i_log_cluster_size; + +for (cluster_idx =0 ; cluster_idx < last_idx; cluster_idx++) { + page_idx = cluster_idx << fi->i_log_cluster_size; + +if (!f2fs_is_compressed_cluster (inode, page_idx)) +continue ; - count = last_idx - page_idx; -while (count && count >= cluster_size) { - ret =redirty_blocks (inode, page_idx, cluster_size); + ret =redirty_blocks (inode, page_idx, fi->i_cluster_size);if (ret <0 )break ;
@@ -4261,9 +4265,6 @@ static int f2fs_ioc_decompress_file(struct file *filp)break ; } - count -= cluster_size; - page_idx += cluster_size; -cond_resched ();if (fatal_signal_pending (current)) { ret = -EINTR ;
@@ -4290,9 +4291,9 @@ static int f2fs_ioc_compress_file(struct file *filp) {struct inode *inode =file_inode (filp);struct f2fs_sb_info *sbi =F2FS_I_SB (inode); -pgoff_t page_idx =0 , last_idx; -int cluster_size =F2FS_I (inode)->i_cluster_size; -int count, ret; +struct f2fs_inode_info *fi =F2FS_I (inode); +pgoff_t page_idx =0 , last_idx, cluster_idx; +int ret;if (!f2fs_sb_has_compression (sbi) ||F2FS_OPTION (sbi).compress_mode !=COMPR_MODE_USER )
@@ -4324,10 +4325,15 @@ static int f2fs_ioc_compress_file(struct file *filp)set_inode_flag (inode,FI_ENABLE_COMPRESS ); last_idx =DIV_ROUND_UP (i_size_read (inode),PAGE_SIZE ); + last_idx >>= fi->i_log_cluster_size; - count = last_idx - page_idx; -while (count && count >= cluster_size) { - ret =redirty_blocks (inode, page_idx, cluster_size); +for (cluster_idx =0 ; cluster_idx < last_idx; cluster_idx++) { + page_idx = cluster_idx << fi->i_log_cluster_size; + +if (f2fs_is_sparse_cluster (inode, page_idx)) +continue ; + + ret =redirty_blocks (inode, page_idx, fi->i_cluster_size);if (ret <0 )break ;
@@ -4337,9 +4343,6 @@ static int f2fs_ioc_compress_file(struct file *filp)break ; } - count -= cluster_size; - page_idx += cluster_size; -cond_resched ();if (fatal_signal_pending (current)) { ret = -EINTR ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 404/634 f2fs: prevent atomic file from being dirtied before commit
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daeho Jeong <[email protected]>
[ Upstream commit fccaa81de87e80b1809906f7e438e5766fbdc172 ]
Keep atomic file clean while updating and make it dirtied during commit in order to avoid unnecessary and excessive inode updates in the previous fix.
--- fs/f2fs/f2fs.h | 2 +- fs/f2fs/inode.c | 5 +++++ fs/f2fs/segment.c | 8 ++++++++ 3 files changed, 14 insertions(+), 1 deletion(-)
fs/f2fs/f2fs.h +1 -1
@@ -803,6 +803,7 @@ enum {FI_ALIGNED_WRITE ,/* enable aligned write */ FI_COW_FILE ,/* indicate COW file */ FI_ATOMIC_COMMITTED ,/* indicate atomic commit completed except disk sync */ +FI_ATOMIC_DIRTIED ,/* indicate atomic file is dirtied */ FI_ATOMIC_REPLACE ,/* indicate atomic replace */ FI_OPENED_FILE ,/* indicate file has been opened */ FI_MAX, /* max flag, never be used */
@@ -3049,7 +3050,6 @@ static inline void __mark_inode_dirty_flag(struct inode *inode,case FI_INLINE_DOTS :case FI_PIN_FILE :case FI_COMPRESS_RELEASED : -case FI_ATOMIC_COMMITTED :f2fs_mark_inode_dirty_sync (inode, true); } }
fs/f2fs/inode.c +5 -0
@@ -35,6 +35,11 @@ void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync)if (f2fs_inode_dirtied (inode, sync))return ; +if (f2fs_is_atomic_file (inode)) { +set_inode_flag (inode,FI_ATOMIC_DIRTIED ); +return ; + } +mark_inode_dirty_sync (inode); }
fs/f2fs/segment.c +8 -0
@@ -199,6 +199,10 @@ void f2fs_abort_atomic_write(struct inode *inode, bool clean)clear_inode_flag (inode,FI_ATOMIC_COMMITTED );clear_inode_flag (inode,FI_ATOMIC_REPLACE );clear_inode_flag (inode,FI_ATOMIC_FILE ); +if (is_inode_flag_set (inode,FI_ATOMIC_DIRTIED )) { +clear_inode_flag (inode,FI_ATOMIC_DIRTIED ); +f2fs_mark_inode_dirty_sync (inode, true); + }stat_dec_atomic_inode (inode);F2FS_I (inode)->atomic_write_task =NULL ;
@@ -366,6 +370,10 @@ static int __f2fs_commit_atomic_write(struct inode *inode) }else { sbi->committed_atomic_block += fi->atomic_write_cnt;set_inode_flag (inode,FI_ATOMIC_COMMITTED ); +if (is_inode_flag_set (inode,FI_ATOMIC_DIRTIED )) { +clear_inode_flag (inode,FI_ATOMIC_DIRTIED ); +f2fs_mark_inode_dirty_sync (inode, true); + } }__complete_revoke_list (inode, &revoke_list, ret ? true : false);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 405/634 f2fs: get rid of online repaire on corrupted directory
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit 884ee6dc85b959bc152f15bca80c30f06069e6c4 ]
syzbot reports a f2fs bug as below:
kernel BUG at fs/f2fs/inode.c:896!
RIP: 0010:f2fs_evict_inode+0x1598/0x15c0 fs/f2fs/inode.c:896 Call Trace: evict+0x532/0x950 fs/inode.c:704 dispose_list fs/inode.c:747 [inline] evict_inodes+0x5f9/0x690 fs/inode.c:797 generic_shutdown_super+0x9d/0x2d0 fs/super.c:627 kill_block_super+0x44/0x90 fs/super.c:1696 kill_f2fs_super+0x344/0x690 fs/f2fs/super.c:4898 deactivate_locked_super+0xc4/0x130 fs/super.c:473 cleanup_mnt+0x41f/0x4b0 fs/namespace.c:1373 task_work_run+0x24f/0x310 kernel/task_work.c:228 ptrace_notify+0x2d2/0x380 kernel/signal.c:2402 ptrace_report_syscall include/linux/ptrace.h:415 [inline] ptrace_report_syscall_exit include/linux/ptrace.h:477 [inline] syscall_exit_work+0xc6/0x190 kernel/entry/common.c:173 syscall_exit_to_user_mode_prepare kernel/entry/common.c:200 [inline] __syscall_exit_to_user_mode_work kernel/entry/common.c:205 [inline] syscall_exit_to_user_mode+0x279/0x370 kernel/entry/common.c:218 do_syscall_64+0x100/0x230 arch/x86/entry/common.c:89 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0010:f2fs_evict_inode+0x1598/0x15c0 fs/f2fs/inode.c:896
Online repaire on corrupted directory in f2fs_lookup() can generate dirty data/meta while racing w/ readonly remount, it may leave dirty inode after filesystem becomes readonly, however, checkpoint() will skips flushing dirty inode in a state of readonly mode, result in above panic.
Let's get rid of online repaire in f2fs_lookup(), and leave the work to fsck.f2fs.
--- fs/f2fs/f2fs.h | 11 ------- fs/f2fs/namei.c | 68 ----------------------------------------- include/linux/f2fs_fs.h | 2 +- 3 files changed, 1 insertion(+), 80 deletions(-)
fs/f2fs/f2fs.h +0 -11
@@ -785,7 +785,6 @@ enum {FI_NEED_IPU ,/* used for ipu per file */ FI_ATOMIC_FILE ,/* indicate atomic file */ FI_DATA_EXIST ,/* indicate data exists */ -FI_INLINE_DOTS ,/* indicate inline dot dentries */ FI_SKIP_WRITES ,/* should skip data page writeback */ FI_OPU_WRITE ,/* used for opu per file */ FI_DIRTY_FILE, /* indicate regular/symlink has dirty pages */
@@ -3047,7 +3046,6 @@ static inline void __mark_inode_dirty_flag(struct inode *inode,return ; fallthrough;case FI_DATA_EXIST : -case FI_INLINE_DOTS :case FI_PIN_FILE :case FI_COMPRESS_RELEASED :f2fs_mark_inode_dirty_sync (inode, true);
@@ -3171,8 +3169,6 @@ static inline void get_inline_info(struct inode *inode, struct f2fs_inode *ri)set_bit (FI_INLINE_DENTRY , fi->flags);if (ri->i_inline &F2FS_DATA_EXIST )set_bit (FI_DATA_EXIST , fi->flags); -if (ri->i_inline &F2FS_INLINE_DOTS ) -set_bit (FI_INLINE_DOTS , fi->flags);if (ri->i_inline &F2FS_EXTRA_ATTR )set_bit (FI_EXTRA_ATTR , fi->flags);if (ri->i_inline &F2FS_PIN_FILE )
@@ -3193,8 +3189,6 @@ static inline void set_raw_inline(struct inode *inode, struct f2fs_inode *ri) ri->i_inline |=F2FS_INLINE_DENTRY ;if (is_inode_flag_set (inode,FI_DATA_EXIST )) ri->i_inline |=F2FS_DATA_EXIST ; -if (is_inode_flag_set (inode,FI_INLINE_DOTS )) - ri->i_inline |=F2FS_INLINE_DOTS ;if (is_inode_flag_set (inode,FI_EXTRA_ATTR )) ri->i_inline |=F2FS_EXTRA_ATTR ;if (is_inode_flag_set (inode,FI_PIN_FILE ))
@@ -3281,11 +3275,6 @@ static inline int f2fs_exist_data(struct inode *inode)return is_inode_flag_set (inode,FI_DATA_EXIST ); } -static inline int f2fs_has_inline_dots (struct inode *inode) -{ -return is_inode_flag_set (inode,FI_INLINE_DOTS ); -} -static inline int f2fs_is_mmap_file (struct inode *inode) {return is_inode_flag_set (inode,FI_MMAP_FILE );
fs/f2fs/namei.c +0 -68
86 lines not on this page · raw message
include/linux/f2fs_fs.h +1 -1
@@ -279,7 +279,7 @@ struct node_footer {#define F2FS_INLINE_DATA 0x02/* file inline data flag */ #define F2FS_INLINE_DENTRY 0x04/* file inline dentry flag */ #define F2FS_DATA_EXIST 0x08/* file inline data exist flag */ -#define F2FS_INLINE_DOTS 0x10/* file having implicit dot dentries */ +#define F2FS_INLINE_DOTS 0x10/* file having implicit dot dentries (obsolete) */ #define F2FS_EXTRA_ATTR 0x20/* file having extra attribute */ #define F2FS_PIN_FILE 0x40/* file should not be gced */ #define F2FS_COMPRESS_RELEASED 0x80/* file released compressed blocks */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 406/634 f2fs: fix to dont set SB_RDONLY in f2fs_handle_critical_error()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit 930c6ab93492c4b15436524e704950b364b2930c ]
syzbot reports a f2fs bug as below:
------------[ cut here ]------------ WARNING: CPU: 1 PID: 58 at kernel/rcu/sync.c:177 rcu_sync_dtor+0xcd/0x180 kernel/rcu/sync.c:177 CPU: 1 UID: 0 PID: 58 Comm: kworker/1:2 Not tainted 6.10.0-syzkaller-12562-g1722389b0d86 #0 Workqueue: events destroy_super_work RIP: 0010:rcu_sync_dtor+0xcd/0x180 kernel/rcu/sync.c:177 Call Trace: percpu_free_rwsem+0x41/0x80 kernel/locking/percpu-rwsem.c:42 destroy_super_work+0xec/0x130 fs/super.c:282 process_one_work kernel/workqueue.c:3231 [inline] process_scheduled_works+0xa2c/0x1830 kernel/workqueue.c:3312 worker_thread+0x86d/0xd40 kernel/workqueue.c:3390 kthread+0x2f0/0x390 kernel/kthread.c:389 ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
As Christian Brauner pointed out [1]: the root cause is f2fs sets SB_RDONLY flag in internal function, rather than setting the flag covered w/ sb->s_umount semaphore via remount procedure, then below race condition causes this bug:
- freeze_super()
- sb_wait_write(sb, SB_FREEZE_WRITE)
- sb_wait_write(sb, SB_FREEZE_PAGEFAULT)
- sb_wait_write(sb, SB_FREEZE_FS)
- f2fs_handle_critical_error
- sb->s_flags |= SB_RDONLY
- thaw_super
- thaw_super_locked
- sb_rdonly() is true, so it skips
sb_freeze_unlock(sb, SB_FREEZE_FS)
- deactivate_locked_super
Since f2fs has almost the same logic as ext4 [2] when handling critical error in filesystem if it mounts w/ errors=remount-ro option:
- set CP_ERROR_FLAG flag which indicates filesystem is stopped
- record errors to superblock
- set SB_RDONLY falg
Once we set CP_ERROR_FLAG flag, all writable interfaces can detect the flag and stop any further updates on filesystem. So, it is safe to not set SB_RDONLY flag, let's remove the logic and keep in line w/ ext4 [3].
[1] https://lore.kernel.org/all/20240729-himbeeren-funknetz-96e62f9c7aee@brauner
[2] https://lore.kernel.org/all/20240729132721.hxih6ehigadqf7wx@quack3
[3] https://lore.kernel.org/linux-ext4/[email protected]
--- fs/f2fs/super.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
fs/f2fs/super.c +6 -4
@@ -4183,12 +4183,14 @@ void f2fs_handle_critical_error(struct f2fs_sb_info *sbi, unsigned char reason, }f2fs_warn (sbi,"Remounting filesystem read-only" ); +/* -* Make sure updated value of ->s_mount_flags will be visible before -* ->s_flags update +* We have already set CP_ERROR_FLAG flag to stop all updates +* to filesystem, so it doesn't need to set SB_RDONLY flag here +* because the flag should be set covered w/ sb->s_umount semaphore +* via remount procedure, otherwise, it will confuse code like +* freeze_super() which will lead to deadlocks and other problems. */ -smp_wmb (); - sb->s_flags |=SB_RDONLY ; }static void f2fs_record_error_work (struct work_struct *work)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 407/634 spi: airoha: fix dirmap_{read,write} operations
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <[email protected]>
[ Upstream commit 2e6bbfe7b0c0607001b784082c2685b134174fac ]
SPI_NFI_READ_FROM_CACHE_DONE bit must be written at the end of dirmap_read operation even if it is already set.
In the same way, SPI_NFI_LOAD_TO_CACHE_DONE bit must be written at the end of dirmap_write operation even if it is already set. For this reason use regmap_write_bits() instead of regmap_set_bits(). This patch fixes mtd_pagetest kernel module test.
--- drivers/spi/spi-airoha-snfi.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
drivers/spi/spi-airoha-snfi.c +14 -4
@@ -739,8 +739,13 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,if (err)return err; - err =regmap_set_bits (as_ctrl->regmap_nfi,REG_SPI_NFI_SNF_STA_CTL1 , -SPI_NFI_READ_FROM_CACHE_DONE ); +/* +* SPI_NFI_READ_FROM_CACHE_DONE bit must be written at the end +* of dirmap_read operation even if it is already set. +*/ + err =regmap_write_bits (as_ctrl->regmap_nfi,REG_SPI_NFI_SNF_STA_CTL1 , +SPI_NFI_READ_FROM_CACHE_DONE , +SPI_NFI_READ_FROM_CACHE_DONE );if (err)return err;
@@ -870,8 +875,13 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,if (err)return err; - err =regmap_set_bits (as_ctrl->regmap_nfi,REG_SPI_NFI_SNF_STA_CTL1 , -SPI_NFI_LOAD_TO_CACHE_DONE ); +/* +* SPI_NFI_LOAD_TO_CACHE_DONE bit must be written at the end +* of dirmap_write operation even if it is already set. +*/ + err =regmap_write_bits (as_ctrl->regmap_nfi,REG_SPI_NFI_SNF_STA_CTL1 , +SPI_NFI_LOAD_TO_CACHE_DONE , +SPI_NFI_LOAD_TO_CACHE_DONE );if (err)return err;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 408/634 spi: airoha: fix airoha_snand_{write,read}_data data_len estimation
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <[email protected]>
[ Upstream commit 0e58637eb968c636725dcd6c7055249b4e5326fb ]
Fix data length written and read in airoha_snand_write_data and airoha_snand_read_data routines respectively if it is bigger than SPI_MAX_TRANSFER_SIZE.
--- drivers/spi/spi-airoha-snfi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/spi/spi-airoha-snfi.c +2 -2
@@ -405,7 +405,7 @@ static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, u8 cmd,for (i =0 ; i < len; i += data_len) {int err; - data_len =min (len,SPI_MAX_TRANSFER_SIZE ); + data_len =min (len - i,SPI_MAX_TRANSFER_SIZE ); err =airoha_snand_set_fifo_op (as_ctrl, cmd, data_len);if (err)return err;
@@ -427,7 +427,7 @@ static int airoha_snand_read_data(struct airoha_snand_ctrl *as_ctrl, u8 *data,for (i =0 ; i < len; i += data_len) {int err; - data_len =min (len,SPI_MAX_TRANSFER_SIZE ); + data_len =min (len - i,SPI_MAX_TRANSFER_SIZE ); err =airoha_snand_set_fifo_op (as_ctrl,0xc , data_len);if (err)return err;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 409/634 spi: atmel-quadspi: Undo runtime PM changes at driver exit time
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit 438efb23f9581659495b85f1f6c7d5946200660c ]
It's important to undo pm_runtime_use_autosuspend() with pm_runtime_dont_use_autosuspend() at driver exit time unless driver initially enabled pm_runtime with devm_pm_runtime_enable() (which handles it for you).
Hence, call pm_runtime_dont_use_autosuspend() at driver exit time to fix it.
--- drivers/spi/atmel-quadspi.c | 1 + 1 file changed, 1 insertion(+)
drivers/spi/atmel-quadspi.c +1 -0
@@ -726,6 +726,7 @@ static void atmel_qspi_remove(struct platform_device *pdev)clk_unprepare (aq->pclk);pm_runtime_disable (&pdev->dev); +pm_runtime_dont_use_autosuspend (&pdev->dev);pm_runtime_put_noidle (&pdev->dev); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 410/634 spi: spi-fsl-lpspi: Undo runtime PM changes at driver exit time
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit 3b577de206d52dbde9428664b6d823d35a803d75 ]
It's important to undo pm_runtime_use_autosuspend() with pm_runtime_dont_use_autosuspend() at driver exit time unless driver initially enabled pm_runtime with devm_pm_runtime_enable() (which handles it for you).
Hence, call pm_runtime_dont_use_autosuspend() at driver exit time to fix it.
--- drivers/spi/spi-fsl-lpspi.c | 1 + 1 file changed, 1 insertion(+)
drivers/spi/spi-fsl-lpspi.c +1 -0
@@ -986,6 +986,7 @@ static void fsl_lpspi_remove(struct platform_device *pdev)fsl_lpspi_dma_exit (controller); +pm_runtime_dont_use_autosuspend (fsl_lpspi->dev);pm_runtime_disable (fsl_lpspi->dev); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 411/634 lib/sbitmap: define swap_lock as raw_spinlock_t
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Lei <[email protected]>
[ Upstream commit 65f666c6203600053478ce8e34a1db269a8701c9 ]
When called from sbitmap_queue_get(), sbitmap_deferred_clear() may be run with preempt disabled. In RT kernel, spin_lock() can sleep, then warning of "BUG: sleeping function called from invalid context" can be triggered.
Fix it by replacing it with raw_spin_lock.
--- include/linux/sbitmap.h | 2 +- lib/sbitmap.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
include/linux/sbitmap.h +1 -1
@@ -40,7 +40,7 @@ struct sbitmap_word {/** * @swap_lock: serializes simultaneous updates of ->word and ->cleared */ -spinlock_t swap_lock; +raw_spinlock_t swap_lock; }____cacheline_aligned_in_smp ;/**
lib/sbitmap.c +2 -2
@@ -65,7 +65,7 @@ static inline bool sbitmap_deferred_clear(struct sbitmap_word *map, {unsigned long mask, word_mask; -guard (spinlock_irqsave)(&map->swap_lock); +guard (raw_spinlock_irqsave)(&map->swap_lock);if (!map->cleared) {if (depth ==0 )
@@ -136,7 +136,7 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift, }for (i =0 ; i < sb->map_nr; i++) -spin_lock_init (&sb->map[i].swap_lock); +raw_spin_lock_init (&sb->map[i].swap_lock);return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 412/634 spi: airoha: remove read cache in airoha_snand_dirmap_read()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <[email protected]>
[ Upstream commit fffca269e4f31c3633c6d810833ba1b184407915 ]
Current upstream driver reports errors running mtd_oobtest kernel module test:
root@OpenWrt:/# insmod mtd_test.ko root@OpenWrt:/# insmod mtd_oobtest.ko dev=5 [ 7023.730584] ================================================= [ 7023.736399] mtd_oobtest: MTD device: 5 [ 7023.740160] mtd_oobtest: MTD device size 3670016, eraseblock size 131072, page size 2048, count of eraseblocks 28, pages per eraseblock 64, OOB size 128 [ 7023.753837] mtd_test: scanning for bad eraseblocks [ 7023.758636] mtd_test: scanned 28 eraseblocks, 0 are bad [ 7023.763861] mtd_oobtest: test 1 of 5 [ 7024.042076] mtd_oobtest: writing OOBs of whole device [ 7024.682069] mtd_oobtest: written up to eraseblock 0 [ 7041.962077] mtd_oobtest: written 28 eraseblocks [ 7041.966626] mtd_oobtest: verifying all eraseblocks [ 7041.972276] mtd_oobtest: error @addr[0x0:0x0] 0xff -> 0xe diff 0xf1 [ 7041.978550] mtd_oobtest: error @addr[0x0:0x1] 0xff -> 0x10 diff 0xef [ 7041.984932] mtd_oobtest: error @addr[0x0:0x2] 0xff -> 0x82 diff 0x7d [ 7041.991293] mtd_oobtest: error @addr[0x0:0x3] 0xff -> 0x10 diff 0xef [ 7041.997659] mtd_oobtest: error @addr[0x0:0x4] 0xff -> 0x0 diff 0xff [ 7042.003942] mtd_oobtest: error @addr[0x0:0x5] 0xff -> 0x8a diff 0x75 [ 7042.010294] mtd_oobtest: error @addr[0x0:0x6] 0xff -> 0x20 diff 0xdf [ 7042.016659] mtd_oobtest: error @addr[0x0:0x7] 0xff -> 0x1 diff 0xfe [ 7042.022935] mtd_oobtest: error @addr[0x0:0x8] 0xff -> 0x2e diff 0xd1 [ 7042.029295] mtd_oobtest: error @addr[0x0:0x9] 0xff -> 0x40 diff 0xbf [ 7042.035661] mtd_oobtest: error @addr[0x0:0xa] 0xff -> 0x0 diff 0xff [ 7042.041935] mtd_oobtest: error @addr[0x0:0xb] 0xff -> 0x89 diff 0x76 [ 7042.048300] mtd_oobtest: error @addr[0x0:0xc] 0xff -> 0x82 diff 0x7d [ 7042.054662] mtd_oobtest: error @addr[0x0:0xd] 0xff -> 0x15 diff 0xea [ 7042.061014] mtd_oobtest: error @addr[0x0:0xe] 0xff -> 0x90 diff 0x6f [ 7042.067380] mtd_oobtest: error @addr[0x0:0xf] 0xff -> 0x0 diff 0xff .... [ 7432.421369] mtd_oobtest: error @addr[0x237800:0x36] 0xff -> 0x5f diff 0xa0 [ 7432.428242] mtd_oobtest: error @addr[0x237800:0x37] 0xff -> 0x21 diff 0xde [ 7432.435118] mtd_oobtest: error: verify failed at 0x237800 [ 7432.440510] mtd_oobtest: error: too many errors [ 7432.445053] mtd_oobtest: error -1 occurred
The above errors are due to the buggy logic in the 'read cache' available in airoha_snand_dirmap_read() routine since there are some corner cases where we are missing data updates. Since we do not get any read/write speed improvement using the cache (according to the mtd_speedtest kernel module test), in order to fix the mtd_oobtest test, remove the 'read cache' in airoha_snand_dirmap_read routine. Now the driver is passing all the tests available in mtd_test suite.
--- drivers/spi/spi-airoha-snfi.c | 21 --------------------- 1 file changed, 21 deletions(-)
drivers/spi/spi-airoha-snfi.c +0 -21
@@ -211,9 +211,6 @@ struct airoha_snand_dev {u8 *txrx_buf;dma_addr_t dma_addr; - -u64 cur_page_num; -bool data_need_update; };struct airoha_snand_ctrl {
@@ -644,11 +641,6 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,u32 val, rd_mode;int err; -if (!as_dev->data_need_update) -return len; - - as_dev->data_need_update = false; -switch (op->cmd.opcode) {case SPI_NAND_OP_READ_FROM_CACHE_DUAL : rd_mode =1 ;
@@ -895,23 +887,11 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,static int airoha_snand_exec_op (struct spi_mem *mem,const struct spi_mem_op *op) { -struct airoha_snand_dev *as_dev =spi_get_ctldata (mem->spi);u8 data[8 ], cmd, opcode = op->cmd.opcode;struct airoha_snand_ctrl *as_ctrl;int i, err; as_ctrl =spi_controller_get_devdata (mem->spi->controller); -if (opcode ==SPI_NAND_OP_PROGRAM_EXECUTE && - op->addr.val == as_dev->cur_page_num) { - as_dev->data_need_update = true; - }else if (opcode ==SPI_NAND_OP_PAGE_READ ) { -if (!as_dev->data_need_update && - op->addr.val == as_dev->cur_page_num) -return 0 ; - - as_dev->data_need_update = true; - as_dev->cur_page_num = op->addr.val; - }/* switch to manual mode */ err =airoha_snand_set_mode (as_ctrl,SPI_MODE_MANUAL );
@@ -996,7 +976,6 @@ static int airoha_snand_setup(struct spi_device *spi)if (dma_mapping_error (as_ctrl->dev, as_dev->dma_addr))return -ENOMEM ; - as_dev->data_need_update = true;spi_set_ctldata (spi, as_dev);return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 413/634 spi: atmel-quadspi: Avoid overwriting delay register settings
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Dahl <[email protected]>
[ Upstream commit 329ca3eed4a9a161515a8714be6ba182321385c7 ]
Previously the MR and SCR registers were just set with the supposedly required values, from cached register values (cached reg content initialized to zero).
All parts fixed here did not consider the current register (cache) content, which would make future support of cs_setup, cs_hold, and cs_inactive impossible.
Setting SCBR in atmel_qspi_setup() erases a possible DLYBS setting from atmel_qspi_set_cs_timing(). The DLYBS setting is applied by ORing over the current setting, without resetting the bits first. All writes to MR did not consider possible settings of DLYCS and DLYBCT.
--- drivers/spi/atmel-quadspi.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/spi/atmel-quadspi.c +8 -6
@@ -375,9 +375,9 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq,* If the QSPI controller is set in regular SPI mode, set it in * Serial Memory Mode (SMM). */ -if (aq->mr !=QSPI_MR_SMM ) { -atmel_qspi_write (QSPI_MR_SMM , aq,QSPI_MR ); - aq->mr =QSPI_MR_SMM ; +if (!(aq->mr &QSPI_MR_SMM )) { + aq->mr |=QSPI_MR_SMM ; +atmel_qspi_write (aq->scr, aq,QSPI_MR ); }/* Clear pending interrupts */
@@ -501,7 +501,8 @@ static int atmel_qspi_setup(struct spi_device *spi)if (ret <0 )return ret; - aq->scr =QSPI_SCR_SCBR (scbr); + aq->scr &= ~QSPI_SCR_SCBR_MASK ; + aq->scr |=QSPI_SCR_SCBR (scbr);atmel_qspi_write (aq->scr, aq,QSPI_SCR );pm_runtime_mark_last_busy (ctrl->dev.parent);
@@ -534,6 +535,7 @@ static int atmel_qspi_set_cs_timing(struct spi_device *spi)if (ret <0 )return ret; + aq->scr &= ~QSPI_SCR_DLYBS_MASK ; aq->scr |=QSPI_SCR_DLYBS (cs_setup);atmel_qspi_write (aq->scr, aq,QSPI_SCR );
@@ -549,8 +551,8 @@ static void atmel_qspi_init(struct atmel_qspi *aq)atmel_qspi_write (QSPI_CR_SWRST , aq,QSPI_CR );/* Set the QSPI controller by default in Serial Memory Mode */ -atmel_qspi_write (QSPI_MR_SMM , aq,QSPI_MR ); - aq->mr =QSPI_MR_SMM ; + aq->mr |=QSPI_MR_SMM ; +atmel_qspi_write (aq->mr, aq,QSPI_MR );/* Enable the QSPI controller */ atmel_qspi_write (QSPI_CR_QSPIEN , aq,QSPI_CR );
Signature · 1 line
2.43.0
Re: [PATCH 6.10 413/634] spi: atmel-quadspi: Avoid overwriting delay register settings
Hello Greg,
Am Wed, Oct 02, 2024 at 02:58:33PM +0200 schrieb Greg Kroah-Hartman:
Quoted 1 line
6.10-stable review patch. If anyone has any objections, please let me know.
Same as for 6.11, if you take this, please also take <[email protected]>.
Thanks
Alex
Quoted 80 lines
------------------
From: Alexander Dahl <[email protected]>
[ Upstream commit
329ca3eed4a9a161515a8714be6ba182321385c7]Previously the MR and SCR registers were just set with the supposedly required values, from cached register values (cached reg content initialized to zero).
All parts fixed here did not consider the current register (cache) content, which would make future support of
cs_setup,cs_hold, andcs_inactiveimpossible.Setting SCBR in
atmel_qspi_setup()erases a possible DLYBS setting fromatmel_qspi_set_cs_timing(). The DLYBS setting is applied by ORing over the current setting, without resetting the bits first. All writes to MR did not consider possible settings of DLYCS and DLYBCT.Signed-off-by Alexander Dahl <[email protected]>Fixes f732646d0ccd ("spi: atmel-quadspi: Add support for configuring CS timing")Signed-off-by Mark Brown <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- drivers/spi/atmel-quadspi.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)drivers/spi/atmel-quadspi.c +8
-6@@ -375,9 +375,9 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq,* If the QSPI controller is set in regular SPI mode, set it in * Serial Memory Mode (SMM). */ -if (aq->mr !=QSPI_MR_SMM ) { -atmel_qspi_write (QSPI_MR_SMM , aq,QSPI_MR ); - aq->mr =QSPI_MR_SMM ; +if (!(aq->mr &QSPI_MR_SMM )) { + aq->mr |=QSPI_MR_SMM ; +atmel_qspi_write (aq->scr, aq,QSPI_MR ); }/* Clear pending interrupts */ @@ -501,7 +501,8 @@ static int atmel_qspi_setup(struct spi_device *spi)if (ret <0 )return ret; - aq->scr =QSPI_SCR_SCBR (scbr); + aq->scr &= ~QSPI_SCR_SCBR_MASK ; + aq->scr |=QSPI_SCR_SCBR (scbr);atmel_qspi_write (aq->scr, aq,QSPI_SCR );pm_runtime_mark_last_busy (ctrl->dev.parent);@@ -534,6 +535,7 @@ static int atmel_qspi_set_cs_timing(struct spi_device *spi)if (ret <0 )return ret; + aq->scr &= ~QSPI_SCR_DLYBS_MASK ; aq->scr |=QSPI_SCR_DLYBS (cs_setup);atmel_qspi_write (aq->scr, aq,QSPI_SCR );@@ -549,8 +551,8 @@ static void atmel_qspi_init(struct atmel_qspi *aq)atmel_qspi_write (QSPI_CR_SWRST , aq,QSPI_CR );/* Set the QSPI controller by default in Serial Memory Mode */ -atmel_qspi_write (QSPI_MR_SMM , aq,QSPI_MR ); - aq->mr =QSPI_MR_SMM ; + aq->mr |=QSPI_MR_SMM ; +atmel_qspi_write (aq->mr, aq,QSPI_MR );/* Enable the QSPI controller */ atmel_qspi_write (QSPI_CR_QSPIEN , aq,QSPI_CR );Signature · 1 line
2.43.0