[PATCH v1 21/26] mm: memcontrol: prepare for reparenting LRU pages for lruvec lock

Qi Zheng posted 26 patches 3 months, 2 weeks ago
There is a newer version of this series
[PATCH v1 21/26] mm: memcontrol: prepare for reparenting LRU pages for lruvec lock
Posted by Qi Zheng 3 months, 2 weeks ago
From: Muchun Song <songmuchun@bytedance.com>

The following diagram illustrates how to ensure the safety of the folio
lruvec lock when LRU folios undergo reparenting.

In the folio_lruvec_lock(folio) function:
```
    rcu_read_lock();
retry:
    lruvec = folio_lruvec(folio);
    /* There is a possibility of folio reparenting at this point. */
    spin_lock(&lruvec->lru_lock);
    if (unlikely(lruvec_memcg(lruvec) != folio_memcg(folio))) {
        /*
         * The wrong lruvec lock was acquired, and a retry is required.
         * This is because the folio resides on the parent memcg lruvec
         * list.
         */
        spin_unlock(&lruvec->lru_lock);
        goto retry;
    }

    /* Reaching here indicates that folio_memcg() is stable. */
```

In the memcg_reparent_objcgs(memcg) function:
```
    spin_lock(&lruvec->lru_lock);
    spin_lock(&lruvec_parent->lru_lock);
    /* Transfer folios from the lruvec list to the parent's. */
    spin_unlock(&lruvec_parent->lru_lock);
    spin_unlock(&lruvec->lru_lock);
```

After acquiring the lruvec lock, it is necessary to verify whether
the folio has been reparented. If reparenting has occurred, the new
lruvec lock must be reacquired. During the LRU folio reparenting
process, the lruvec lock will also be acquired (this will be
implemented in a subsequent patch). Therefore, folio_memcg() remains
unchanged while the lruvec lock is held.

Given that lruvec_memcg(lruvec) is always equal to folio_memcg(folio)
after the lruvec lock is acquired, the lruvec_memcg_debug() check is
redundant. Hence, it is removed.

This patch serves as a preparation for the reparenting of LRU folios.

Signed-off-by: Muchun Song <songmuchun@bytedance.com>
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
---
 include/linux/memcontrol.h | 23 ++++++-----------
 mm/compaction.c            | 29 ++++++++++++++++-----
 mm/memcontrol.c            | 53 +++++++++++++++++++-------------------
 3 files changed, 58 insertions(+), 47 deletions(-)

diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index ca8d4e09cbe7d..6f6b28f8f0f63 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -740,7 +740,11 @@ static inline struct lruvec *mem_cgroup_lruvec(struct mem_cgroup *memcg,
  * folio_lruvec - return lruvec for isolating/putting an LRU folio
  * @folio: Pointer to the folio.
  *
- * This function relies on folio->mem_cgroup being stable.
+ * The user should hold an rcu read lock to protect lruvec associated with
+ * the folio from being released. But it does not prevent binding stability
+ * between the folio and the returned lruvec from being changed to its parent
+ * or ancestor (e.g. like folio_lruvec_lock() does that holds LRU lock to
+ * prevent the change).
  */
 static inline struct lruvec *folio_lruvec(struct folio *folio)
 {
@@ -763,15 +767,6 @@ struct lruvec *folio_lruvec_lock_irq(struct folio *folio);
 struct lruvec *folio_lruvec_lock_irqsave(struct folio *folio,
 						unsigned long *flags);
 
-#ifdef CONFIG_DEBUG_VM
-void lruvec_memcg_debug(struct lruvec *lruvec, struct folio *folio);
-#else
-static inline
-void lruvec_memcg_debug(struct lruvec *lruvec, struct folio *folio)
-{
-}
-#endif
-
 static inline
 struct mem_cgroup *mem_cgroup_from_css(struct cgroup_subsys_state *css){
 	return css ? container_of(css, struct mem_cgroup, css) : NULL;
@@ -1204,11 +1199,6 @@ static inline struct lruvec *folio_lruvec(struct folio *folio)
 	return &pgdat->__lruvec;
 }
 
-static inline
-void lruvec_memcg_debug(struct lruvec *lruvec, struct folio *folio)
-{
-}
-
 static inline struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg)
 {
 	return NULL;
@@ -1515,17 +1505,20 @@ static inline struct lruvec *parent_lruvec(struct lruvec *lruvec)
 static inline void lruvec_unlock(struct lruvec *lruvec)
 {
 	spin_unlock(&lruvec->lru_lock);
+	rcu_read_unlock();
 }
 
 static inline void lruvec_unlock_irq(struct lruvec *lruvec)
 {
 	spin_unlock_irq(&lruvec->lru_lock);
+	rcu_read_unlock();
 }
 
 static inline void lruvec_unlock_irqrestore(struct lruvec *lruvec,
 		unsigned long flags)
 {
 	spin_unlock_irqrestore(&lruvec->lru_lock, flags);
+	rcu_read_unlock();
 }
 
 /* Test requires a stable folio->memcg binding, see folio_memcg() */
diff --git a/mm/compaction.c b/mm/compaction.c
index 4dce180f699b4..0d2a0e6239eb4 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -518,6 +518,24 @@ static bool compact_lock_irqsave(spinlock_t *lock, unsigned long *flags,
 	return true;
 }
 
+static struct lruvec *
+compact_folio_lruvec_lock_irqsave(struct folio *folio, unsigned long *flags,
+				  struct compact_control *cc)
+{
+	struct lruvec *lruvec;
+
+	rcu_read_lock();
+retry:
+	lruvec = folio_lruvec(folio);
+	compact_lock_irqsave(&lruvec->lru_lock, flags, cc);
+	if (unlikely(lruvec_memcg(lruvec) != folio_memcg(folio))) {
+		spin_unlock_irqrestore(&lruvec->lru_lock, *flags);
+		goto retry;
+	}
+
+	return lruvec;
+}
+
 /*
  * Compaction requires the taking of some coarse locks that are potentially
  * very heavily contended. The lock should be periodically unlocked to avoid
@@ -839,7 +857,7 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
 {
 	pg_data_t *pgdat = cc->zone->zone_pgdat;
 	unsigned long nr_scanned = 0, nr_isolated = 0;
-	struct lruvec *lruvec;
+	struct lruvec *lruvec = NULL;
 	unsigned long flags = 0;
 	struct lruvec *locked = NULL;
 	struct folio *folio = NULL;
@@ -1153,18 +1171,17 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
 		if (!folio_test_clear_lru(folio))
 			goto isolate_fail_put;
 
-		lruvec = folio_lruvec(folio);
+		if (locked)
+			lruvec = folio_lruvec(folio);
 
 		/* If we already hold the lock, we can skip some rechecking */
-		if (lruvec != locked) {
+		if (lruvec != locked || !locked) {
 			if (locked)
 				lruvec_unlock_irqrestore(locked, flags);
 
-			compact_lock_irqsave(&lruvec->lru_lock, &flags, cc);
+			lruvec = compact_folio_lruvec_lock_irqsave(folio, &flags, cc);
 			locked = lruvec;
 
-			lruvec_memcg_debug(lruvec, folio);
-
 			/*
 			 * Try get exclusive access under lock. If marked for
 			 * skip, the scan is aborted unless the current context
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 4b3c7d4f346b5..7969dd93d858a 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1184,23 +1184,6 @@ void mem_cgroup_scan_tasks(struct mem_cgroup *memcg,
 	}
 }
 
-#ifdef CONFIG_DEBUG_VM
-void lruvec_memcg_debug(struct lruvec *lruvec, struct folio *folio)
-{
-	struct mem_cgroup *memcg;
-
-	if (mem_cgroup_disabled())
-		return;
-
-	memcg = folio_memcg(folio);
-
-	if (!memcg)
-		VM_BUG_ON_FOLIO(!mem_cgroup_is_root(lruvec_memcg(lruvec)), folio);
-	else
-		VM_BUG_ON_FOLIO(lruvec_memcg(lruvec) != memcg, folio);
-}
-#endif
-
 /**
  * folio_lruvec_lock - Lock the lruvec for a folio.
  * @folio: Pointer to the folio.
@@ -1210,14 +1193,20 @@ void lruvec_memcg_debug(struct lruvec *lruvec, struct folio *folio)
  * - folio_test_lru false
  * - folio frozen (refcount of 0)
  *
- * Return: The lruvec this folio is on with its lock held.
+ * Return: The lruvec this folio is on with its lock held and rcu read lock held.
  */
 struct lruvec *folio_lruvec_lock(struct folio *folio)
 {
-	struct lruvec *lruvec = folio_lruvec(folio);
+	struct lruvec *lruvec;
 
+	rcu_read_lock();
+retry:
+	lruvec = folio_lruvec(folio);
 	spin_lock(&lruvec->lru_lock);
-	lruvec_memcg_debug(lruvec, folio);
+	if (unlikely(lruvec_memcg(lruvec) != folio_memcg(folio))) {
+		spin_unlock(&lruvec->lru_lock);
+		goto retry;
+	}
 
 	return lruvec;
 }
@@ -1232,14 +1221,20 @@ struct lruvec *folio_lruvec_lock(struct folio *folio)
  * - folio frozen (refcount of 0)
  *
  * Return: The lruvec this folio is on with its lock held and interrupts
- * disabled.
+ * disabled and rcu read lock held.
  */
 struct lruvec *folio_lruvec_lock_irq(struct folio *folio)
 {
-	struct lruvec *lruvec = folio_lruvec(folio);
+	struct lruvec *lruvec;
 
+	rcu_read_lock();
+retry:
+	lruvec = folio_lruvec(folio);
 	spin_lock_irq(&lruvec->lru_lock);
-	lruvec_memcg_debug(lruvec, folio);
+	if (unlikely(lruvec_memcg(lruvec) != folio_memcg(folio))) {
+		spin_unlock_irq(&lruvec->lru_lock);
+		goto retry;
+	}
 
 	return lruvec;
 }
@@ -1255,15 +1250,21 @@ struct lruvec *folio_lruvec_lock_irq(struct folio *folio)
  * - folio frozen (refcount of 0)
  *
  * Return: The lruvec this folio is on with its lock held and interrupts
- * disabled.
+ * disabled and rcu read lock held.
  */
 struct lruvec *folio_lruvec_lock_irqsave(struct folio *folio,
 		unsigned long *flags)
 {
-	struct lruvec *lruvec = folio_lruvec(folio);
+	struct lruvec *lruvec;
 
+	rcu_read_lock();
+retry:
+	lruvec = folio_lruvec(folio);
 	spin_lock_irqsave(&lruvec->lru_lock, *flags);
-	lruvec_memcg_debug(lruvec, folio);
+	if (unlikely(lruvec_memcg(lruvec) != folio_memcg(folio))) {
+		spin_unlock_irqrestore(&lruvec->lru_lock, *flags);
+		goto retry;
+	}
 
 	return lruvec;
 }
-- 
2.20.1
Re: [PATCH v1 21/26] mm: memcontrol: prepare for reparenting LRU pages for lruvec lock
Posted by Harry Yoo 2 months, 2 weeks ago
On Tue, Oct 28, 2025 at 09:58:34PM +0800, Qi Zheng wrote:
> From: Muchun Song <songmuchun@bytedance.com>
> 
> The following diagram illustrates how to ensure the safety of the folio
> lruvec lock when LRU folios undergo reparenting.
> 
> In the folio_lruvec_lock(folio) function:
> ```
>     rcu_read_lock();
> retry:
>     lruvec = folio_lruvec(folio);
>     /* There is a possibility of folio reparenting at this point. */
>     spin_lock(&lruvec->lru_lock);
>     if (unlikely(lruvec_memcg(lruvec) != folio_memcg(folio))) {
>         /*
>          * The wrong lruvec lock was acquired, and a retry is required.
>          * This is because the folio resides on the parent memcg lruvec
>          * list.
>          */
>         spin_unlock(&lruvec->lru_lock);
>         goto retry;
>     }
> 
>     /* Reaching here indicates that folio_memcg() is stable. */

Does that mean we call rcu_read_unlock() in lruvec_unlock() instead of
in folio_lruvec_lock() only to avoid false warnings inside the critical
section, and technically calling rcu_read_unlock() right after acquiring
the spinlock is fine?

-- 
Cheers,
Harry / Hyeonggon

> ```
> 
> In the memcg_reparent_objcgs(memcg) function:
> ```
>     spin_lock(&lruvec->lru_lock);
>     spin_lock(&lruvec_parent->lru_lock);
>     /* Transfer folios from the lruvec list to the parent's. */
>     spin_unlock(&lruvec_parent->lru_lock);
>     spin_unlock(&lruvec->lru_lock);
> ```
> 
> After acquiring the lruvec lock, it is necessary to verify whether
> the folio has been reparented. If reparenting has occurred, the new
> lruvec lock must be reacquired. During the LRU folio reparenting
> process, the lruvec lock will also be acquired (this will be
> implemented in a subsequent patch). Therefore, folio_memcg() remains
> unchanged while the lruvec lock is held.
> 
> Given that lruvec_memcg(lruvec) is always equal to folio_memcg(folio)
> after the lruvec lock is acquired, the lruvec_memcg_debug() check is
> redundant. Hence, it is removed.
> 
> This patch serves as a preparation for the reparenting of LRU folios.
> 
> Signed-off-by: Muchun Song <songmuchun@bytedance.com>
> Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
> ---
Re: [PATCH v1 21/26] mm: memcontrol: prepare for reparenting LRU pages for lruvec lock
Posted by Qi Zheng 2 months, 2 weeks ago

On 11/21/25 11:15 AM, Harry Yoo wrote:
> On Tue, Oct 28, 2025 at 09:58:34PM +0800, Qi Zheng wrote:
>> From: Muchun Song <songmuchun@bytedance.com>
>>
>> The following diagram illustrates how to ensure the safety of the folio
>> lruvec lock when LRU folios undergo reparenting.
>>
>> In the folio_lruvec_lock(folio) function:
>> ```
>>      rcu_read_lock();
>> retry:
>>      lruvec = folio_lruvec(folio);
>>      /* There is a possibility of folio reparenting at this point. */
>>      spin_lock(&lruvec->lru_lock);
>>      if (unlikely(lruvec_memcg(lruvec) != folio_memcg(folio))) {
>>          /*
>>           * The wrong lruvec lock was acquired, and a retry is required.
>>           * This is because the folio resides on the parent memcg lruvec
>>           * list.
>>           */
>>          spin_unlock(&lruvec->lru_lock);
>>          goto retry;
>>      }
>>
>>      /* Reaching here indicates that folio_memcg() is stable. */
> 
> Does that mean we call rcu_read_unlock() in lruvec_unlock() instead of
> in folio_lruvec_lock() only to avoid false warnings inside the critical

Right.

> section, and technically calling rcu_read_unlock() right after acquiring
> the spinlock is fine?

Right.

>
Re: [PATCH v1 21/26] mm: memcontrol: prepare for reparenting LRU pages for lruvec lock
Posted by kernel test robot 3 months, 1 week ago

Hello,

kernel test robot noticed "WARNING:bad_unlock_balance_detected" on:

commit: dd9e066d9677ca28748a63b16b33c858af75164b ("[PATCH v1 21/26] mm: memcontrol: prepare for reparenting LRU pages for lruvec lock")
url: https://github.com/intel-lab-lkp/linux/commits/Qi-Zheng/mm-memcontrol-remove-dead-code-of-checking-parent-memory-cgroup/20251028-221021
base: https://git.kernel.org/cgit/linux/kernel/git/akpm/mm.git mm-everything
patch link: https://lore.kernel.org/all/d5d72d101212e9fb82727c941d581c68728c7f53.1761658311.git.zhengqi.arch@bytedance.com/
patch subject: [PATCH v1 21/26] mm: memcontrol: prepare for reparenting LRU pages for lruvec lock

in testcase: boot

config: i386-randconfig-141-20251031
compiler: gcc-14
test machine: qemu-system-i386 -enable-kvm -cpu SandyBridge -smp 2 -m 4G

(please refer to attached dmesg/kmsg for entire log/backtrace)


+-----------------------------------------------------------------------------------+------------+------------+
|                                                                                   | c856dae1f8 | dd9e066d96 |
+-----------------------------------------------------------------------------------+------------+------------+
| WARNING:bad_unlock_balance_detected                                               | 0          | 87         |
| is_trying_to_release_lock(rcu_read_lock)at                                        | 0          | 87         |
| calltrace:rcu_read_unlock                                                         | 0          | 87         |
| WARNING:at_kernel/rcu/tree_plugin.h:#__rcu_read_unlock                            | 0          | 87         |
| EIP:__rcu_read_unlock                                                             | 0          | 87         |
| BUG:sleeping_function_called_from_invalid_context_at_mm/filemap.c                 | 0          | 87         |
| WARNING:at_kernel/rcu/tree_plugin.h:#rcu_sched_clock_irq                          | 0          | 87         |
| EIP:rcu_sched_clock_irq                                                           | 0          | 87         |
| EIP:evm_inode_alloc_security                                                      | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_include/linux/percpu-rwsem.h | 0          | 84         |
| BUG:sleeping_function_called_from_invalid_context_at_include/linux/sched/mm.h     | 0          | 86         |
| BUG:workqueue_leaked_atomic,lock_or_RCU:kworker##[#]                              | 0          | 84         |
| BUG:sleeping_function_called_from_invalid_context_at_mm/slab_common.c             | 0          | 23         |
| BUG:sleeping_function_called_from_invalid_context_at_kernel/workqueue.c           | 0          | 60         |
| BUG:sleeping_function_called_from_invalid_context_at_kernel/locking/rwsem.c       | 0          | 73         |
| BUG:sleeping_function_called_from_invalid_context_at_lib/strncpy_from_user.c      | 0          | 41         |
| BUG:sleeping_function_called_from_invalid_context_at_mm/mmap.c                    | 0          | 16         |
| BUG:sleeping_function_called_from_invalid_context_at_kernel/locking/mutex.c       | 0          | 70         |
| BUG:sleeping_function_called_from_invalid_context_at_include/linux/uaccess.h      | 0          | 40         |
| BUG:sleeping_function_called_from_invalid_context_at_mm/memory.c                  | 0          | 55         |
| EIP:kmem_cache_alloc_noprof                                                       | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_fs/dcache.c                  | 0          | 69         |
| BUG:sleeping_function_called_from_invalid_context_at_fs/file_table.c              | 0          | 32         |
| BUG:sleeping_function_called_from_invalid_context_at_kernel/task_work.c           | 0          | 25         |
| BUG:sleeping_function_called_from_invalid_context_at_arch/x86/entry/syscall_32.c  | 0          | 46         |
| WARNING:at_kernel/rcu/tree_exp.h:#rcu_exp_handler                                 | 0          | 58         |
| EIP:rcu_exp_handler                                                               | 0          | 58         |
| EIP:find_bug                                                                      | 0          | 13         |
| BUG:sleeping_function_called_from_invalid_context_at_fs/pidfs.c                   | 0          | 9          |
| EIP:_parse_integer_limit                                                          | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_lib/iov_iter.c               | 0          | 64         |
| EIP:ep_poll                                                                       | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_mm/mmu_gather.c              | 0          | 18         |
| BUG:sleeping_function_called_from_invalid_context_at_fs/select.c                  | 0          | 12         |
| BUG:sleeping_function_called_from_invalid_context_at_net/core/sock.c              | 0          | 15         |
| EIP:handle_bug                                                                    | 0          | 25         |
| BUG:sleeping_function_called_from_invalid_context_at_include/linux/pagemap.h      | 0          | 14         |
| EIP:inflate_fast                                                                  | 0          | 20         |
| EIP:zlib_inflate_table                                                            | 0          | 2          |
| BUG:sleeping_function_called_from_invalid_context_at_mm/shmem.c                   | 0          | 2          |
| EIP:unwind_get_return_address                                                     | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_mm/vma.c                     | 0          | 11         |
| EIP:kmem_cache_alloc_lru_noprof                                                   | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_mm/mprotect.c                | 0          | 2          |
| EIP:console_emit_next_record                                                      | 0          | 10         |
| EIP:dump_stack_lvl                                                                | 0          | 31         |
| BUG:sleeping_function_called_from_invalid_context_at_include/linux/mmu_notifier.h | 0          | 13         |
| BUG:sleeping_function_called_from_invalid_context_at_mm/vmalloc.c                 | 0          | 2          |
| BUG:sleeping_function_called_from_invalid_context_at_kernel/nsproxy.c             | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_fs/exec.c                    | 0          | 1          |
| EIP:preempt_count_sub                                                             | 0          | 1          |
| EIP:kunmap_local_indexed                                                          | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_mm/gup.c                     | 0          | 2          |
| EIP:seqcount_lockdep_reader_access                                                | 0          | 1          |
| EIP:_raw_spin_unlock_irqrestore                                                   | 0          | 5          |
| BUG:sleeping_function_called_from_invalid_context_at_kernel/exit.c                | 0          | 2          |
| BUG:sleeping_function_called_from_invalid_context_at_mm/rmap.c                    | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_mm/truncate.c                | 0          | 1          |
| EIP:finish_task_switch                                                            | 0          | 2          |
| EIP:inode_init_once                                                               | 0          | 1          |
| EIP:check_lifetime                                                                | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_fs/namei.c                   | 0          | 3          |
| BUG:sleeping_function_called_from_invalid_context_at_fs/readdir.c                 | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_kernel/rcu/srcutree.c        | 0          | 1          |
| EIP:memset_no_sanitize_memory                                                     | 0          | 1          |
| EIP:lookup_one_qstr_excl                                                          | 0          | 1          |
| EIP:__up_read                                                                     | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_fs/file.c                    | 0          | 3          |
| EIP:ramfs_symlink                                                                 | 0          | 1          |
| EIP:do_dentry_open                                                                | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_kernel/printk/printk.c       | 0          | 1          |
| EIP:unwind_next_frame                                                             | 0          | 1          |
| EIP:handle_softirqs                                                               | 0          | 1          |
| EIP:bad_range                                                                     | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_include/linux/freezer.h      | 0          | 2          |
| EIP:security_file_open                                                            | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_kernel/fork.c                | 0          | 2          |
| EIP:kernel_init_pages                                                             | 0          | 1          |
| EIP:filemap_add_folio                                                             | 0          | 1          |
| EIP:update_stack_state                                                            | 0          | 1          |
| EIP:folio_nr_pages                                                                | 0          | 1          |
| EIP:mntput                                                                        | 0          | 1          |
| BUG:sleeping_function_called_from_invalid_context_at_kernel/sched/completion.c    | 0          | 1          |
| EIP:__alloc_frozen_pages_noprof                                                   | 0          | 1          |
| EIP:unwind_get_return_address_ptr                                                 | 0          | 1          |
| EIP:copy_folio_from_iter_atomic                                                   | 0          | 1          |
| EIP:filp_flush                                                                    | 0          | 1          |
| EIP:__put_user_4                                                                  | 0          | 2          |
| EIP:balance_dirty_pages_ratelimited_flags                                         | 0          | 1          |
| EIP:zlib_updatewindow                                                             | 0          | 1          |
+-----------------------------------------------------------------------------------+------------+------------+


If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202511041421.784bbd5e-lkp@intel.com


[    1.392214][   T45] WARNING: bad unlock balance detected!
[    1.393285][   T45] 6.18.0-rc3-00251-gdd9e066d9677 #1 Not tainted
[    1.394579][   T45] -------------------------------------
[    1.395442][   T45] kworker/u9:1/45 is trying to release lock (rcu_read_lock) at:
[    1.396977][   T45] rcu_read_unlock (include/linux/rcupdate.h:341 include/linux/rcupdate.h:897)
[    1.398160][   T45] but there are no more locks to release!
[    1.399337][   T45]
[    1.399337][   T45] other info that might help us debug this:
[    1.399707][   T45] 5 locks held by kworker/u9:1/45:
[    1.399707][   T45]  #0: c01ad6c4 ((wq_completion)async){+.+.}-{0:0}, at: process_one_work (kernel/workqueue.c:3238)
[    1.399707][   T45]  #1: c08e9f18 ((work_completion)(&entry->work)){+.+.}-{0:0}, at: process_one_work (kernel/workqueue.c:3239)
[    1.399707][   T45]  #2: c02ed27c (sb_writers#2){.+.+}-{0:0}, at: file_start_write+0x1e/0x30
[    1.399707][   T45]  #3: c042e0ec (&sb->s_type->i_mutex_key){++++}-{4:4}, at: generic_file_write_iter (mm/filemap.c:4404)
[    1.399707][   T45]  #4: eaa771a0 (lock#3){+.+.}-{3:3}, at: local_lock_acquire (include/linux/local_lock_internal.h:40)
[    1.399707][   T45]
[    1.399707][   T45] stack backtrace:
[    1.399707][   T45] CPU: 0 UID: 0 PID: 45 Comm: kworker/u9:1 Not tainted 6.18.0-rc3-00251-gdd9e066d9677 #1 PREEMPT(none)
[    1.399707][   T45] Workqueue: async async_run_entry_fn
[    1.399707][   T45] Call Trace:
[    1.399707][   T45]  dump_stack_lvl (lib/dump_stack.c:122)
[    1.399707][   T45]  ? rcu_read_unlock (include/linux/rcupdate.h:341 include/linux/rcupdate.h:897)
[    1.399707][   T45]  dump_stack (lib/dump_stack.c:130)
[    1.399707][   T45]  print_unlock_imbalance_bug (kernel/locking/lockdep.c:5300 kernel/locking/lockdep.c:5272)
[    1.399707][   T45]  ? rcu_read_unlock (include/linux/rcupdate.h:341 include/linux/rcupdate.h:897)
[    1.399707][   T45]  __lock_release+0x5e/0x150
[    1.399707][   T45]  ? rcu_read_unlock (include/linux/rcupdate.h:341 include/linux/rcupdate.h:897)
[    1.399707][   T45]  lock_release (kernel/locking/lockdep.c:470 kernel/locking/lockdep.c:5891 kernel/locking/lockdep.c:5875)
[    1.399707][   T45]  ? lru_deactivate_file (mm/swap.c:119)
[    1.399707][   T45]  rcu_read_unlock (include/linux/rcupdate.h:899)
[    1.399707][   T45]  lruvec_unlock_irqrestore (include/linux/memcontrol.h:1522)
[    1.399707][   T45]  folio_batch_move_lru (include/linux/mm.h:1501 mm/swap.c:179)
[    1.399707][   T45]  __folio_batch_add_and_move (mm/swap.c:196 (discriminator 2))
[    1.399707][   T45]  ? lru_deactivate_file (mm/swap.c:119)
[    1.399707][   T45]  folio_add_lru (mm/swap.c:514)
[    1.399707][   T45]  filemap_add_folio (mm/filemap.c:996)
[    1.399707][   T45]  __filemap_get_folio (mm/filemap.c:2023)
[    1.399707][   T45]  simple_write_begin (fs/libfs.c:932 (discriminator 1))
[    1.399707][   T45]  generic_perform_write (mm/filemap.c:4263)
[    1.399707][   T45]  __generic_file_write_iter (mm/filemap.c:4380)
[    1.399707][   T45]  generic_file_write_iter (mm/filemap.c:4406)
[    1.399707][   T45]  __kernel_write_iter (fs/read_write.c:619)
[    1.399707][   T45]  __kernel_write (fs/read_write.c:640)
[    1.399707][   T45]  kernel_write (fs/read_write.c:660 fs/read_write.c:650)
[    1.399707][   T45]  xwrite+0x27/0x80
[    1.399707][   T45]  do_copy (init/initramfs.c:417 (discriminator 1))
[    1.399707][   T45]  write_buffer (init/initramfs.c:470 (discriminator 1))
[    1.399707][   T45]  flush_buffer (init/initramfs.c:482 (discriminator 1))
[    1.399707][   T45]  __gunzip+0x21d/0x2c0
[    1.399707][   T45]  ? bunzip2 (lib/decompress_inflate.c:39)
[    1.399707][   T45]  ? __gunzip+0x2c0/0x2c0
[    1.399707][   T45]  gunzip (lib/decompress_inflate.c:208)
[    1.399707][   T45]  ? write_buffer (init/initramfs.c:476)
[    1.399707][   T45]  ? initrd_load (init/initramfs.c:64)
[    1.399707][   T45]  unpack_to_rootfs (init/initramfs.c:553)
[    1.399707][   T45]  ? write_buffer (init/initramfs.c:476)
[    1.399707][   T45]  ? initrd_load (init/initramfs.c:64)
[    1.399707][   T45]  ? reserve_initrd_mem (init/initramfs.c:719)
[    1.399707][   T45]  do_populate_rootfs (init/initramfs.c:734)
[    1.399707][   T45]  async_run_entry_fn (kernel/async.c:136 (discriminator 1))
[    1.399707][   T45]  ? async_schedule_node (kernel/async.c:118)
[    1.399707][   T45]  process_one_work (arch/x86/include/asm/atomic.h:23 include/linux/atomic/atomic-arch-fallback.h:457 include/linux/jump_label.h:262 include/trace/events/workqueue.h:110 kernel/workqueue.c:3268)
[    1.399707][   T45]  process_scheduled_works (kernel/workqueue.c:3346)
[    1.399707][   T45]  worker_thread (include/linux/list.h:381 (discriminator 2) kernel/workqueue.c:952 (discriminator 2) kernel/workqueue.c:3428 (discriminator 2))
[    1.399707][   T45]  kthread (kernel/kthread.c:465)
[    1.399707][   T45]  ? process_scheduled_works (kernel/workqueue.c:3373)
[    1.399707][   T45]  ? kthread_is_per_cpu (kernel/kthread.c:412)
[    1.399707][   T45]  ret_from_fork (arch/x86/kernel/process.c:164)
[    1.399707][   T45]  ? kthread_is_per_cpu (kernel/kthread.c:412)
[    1.399707][   T45]  ret_from_fork_asm (arch/x86/entry/entry_32.S:737)
[    1.399707][   T45]  entry_INT80_32 (arch/x86/entry/entry_32.S:945)
[    1.467118][   T32] Callback from call_rcu_tasks() invoked.
[    1.468370][   T45] ------------[ cut here ]------------
[    1.469508][   T45] WARNING: CPU: 0 PID: 45 at kernel/rcu/tree_plugin.h:443 __rcu_read_unlock (kernel/rcu/tree_plugin.h:443)
[    1.471711][   T45] Modules linked in:
[    1.472490][   T45] CPU: 0 UID: 0 PID: 45 Comm: kworker/u9:1 Not tainted 6.18.0-rc3-00251-gdd9e066d9677 #1 PREEMPT(none)
[    1.474777][   T45] Workqueue: async async_run_entry_fn
[    1.475823][   T45] EIP: __rcu_read_unlock (kernel/rcu/tree_plugin.h:443)
[    1.476872][   T45] Code: 0c d0 56 c2 ff 8b a4 02 00 00 75 11 8b 83 a8 02 00 00 85 c0 74 07 89 d8 e8 7c fe ff ff 8b 83 a4 02 00 00 3d ff ff ff 3f 76 02 <0f> 0b 5b 5d 31 c0 c3 2e 8d b4 26 00 00 00 00 55 89 e5 57 56 89 c6
All code
========
   0:	0c d0                	or     $0xd0,%al
   2:	56                   	push   %rsi
   3:	c2 ff 8b             	ret    $0x8bff
   6:	a4                   	movsb  %ds:(%rsi),%es:(%rdi)
   7:	02 00                	add    (%rax),%al
   9:	00 75 11             	add    %dh,0x11(%rbp)
   c:	8b 83 a8 02 00 00    	mov    0x2a8(%rbx),%eax
  12:	85 c0                	test   %eax,%eax
  14:	74 07                	je     0x1d
  16:	89 d8                	mov    %ebx,%eax
  18:	e8 7c fe ff ff       	call   0xfffffffffffffe99
  1d:	8b 83 a4 02 00 00    	mov    0x2a4(%rbx),%eax
  23:	3d ff ff ff 3f       	cmp    $0x3fffffff,%eax
  28:	76 02                	jbe    0x2c
  2a:*	0f 0b                	ud2		<-- trapping instruction
  2c:	5b                   	pop    %rbx
  2d:	5d                   	pop    %rbp
  2e:	31 c0                	xor    %eax,%eax
  30:	c3                   	ret
  31:	2e 8d b4 26 00 00 00 	cs lea 0x0(%rsi,%riz,1),%esi
  38:	00 
  39:	55                   	push   %rbp
  3a:	89 e5                	mov    %esp,%ebp
  3c:	57                   	push   %rdi
  3d:	56                   	push   %rsi
  3e:	89 c6                	mov    %eax,%esi

Code starting with the faulting instruction
===========================================
   0:	0f 0b                	ud2
   2:	5b                   	pop    %rbx
   3:	5d                   	pop    %rbp
   4:	31 c0                	xor    %eax,%eax
   6:	c3                   	ret
   7:	2e 8d b4 26 00 00 00 	cs lea 0x0(%rsi,%riz,1),%esi
   e:	00 
   f:	55                   	push   %rbp
  10:	89 e5                	mov    %esp,%ebp
  12:	57                   	push   %rdi
  13:	56                   	push   %rsi
  14:	89 c6                	mov    %eax,%esi
[    1.480862][   T45] EAX: ffffffff EBX: c0bfd640 ECX: 00000000 EDX: 00000000
[    1.482292][   T45] ESI: eaa771c0 EDI: c119e160 EBP: c08e9c0c ESP: c08e9c08
[    1.483721][   T45] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 EFLAGS: 00010286
[    1.485350][   T45] CR0: 80050033 CR2: ffbff000 CR3: 026c6000 CR4: 000006f0
[    1.486725][   T45] Call Trace:
[    1.487465][   T45]  rcu_read_unlock (include/linux/rcupdate.h:900)
[    1.488404][   T45]  lruvec_unlock_irqrestore (include/linux/memcontrol.h:1522)
[    1.489570][   T45]  folio_batch_move_lru (include/linux/mm.h:1501 mm/swap.c:179)
[    1.491100][   T45]  __folio_batch_add_and_move (mm/swap.c:196 (discriminator 2))
[    1.492318][   T45]  ? lru_deactivate_file (mm/swap.c:119)
[    1.493827][   T45]  folio_add_lru (mm/swap.c:514)
[    1.494817][   T45]  filemap_add_folio (mm/filemap.c:996)
[    1.495891][   T45]  __filemap_get_folio (mm/filemap.c:2023)
[    1.497735][   T45]  simple_write_begin (fs/libfs.c:932 (discriminator 1))
[    1.498813][   T45]  generic_perform_write (mm/filemap.c:4263)
[    1.500292][   T45]  __generic_file_write_iter (mm/filemap.c:4380)
[    1.501552][   T45]  generic_file_write_iter (mm/filemap.c:4406)
[    1.502790][   T45]  __kernel_write_iter (fs/read_write.c:619)
[    1.504090][   T45]  __kernel_write (fs/read_write.c:640)
[    1.505377][   T45]  kernel_write (fs/read_write.c:660 fs/read_write.c:650)
[    1.506306][   T45]  xwrite+0x27/0x80
[    1.507429][   T45]  do_copy (init/initramfs.c:417 (discriminator 1))
[    1.508361][   T45]  write_buffer (init/initramfs.c:470 (discriminator 1))
[    1.509300][   T45]  flush_buffer (init/initramfs.c:482 (discriminator 1))
[    1.510307][   T45]  __gunzip+0x21d/0x2c0
[    1.511424][   T45]  ? bunzip2 (lib/decompress_inflate.c:39)
[    1.512312][   T45]  ? __gunzip+0x2c0/0x2c0
[    1.513515][   T45]  gunzip (lib/decompress_inflate.c:208)
[    1.514359][   T45]  ? write_buffer (init/initramfs.c:476)
[    1.515304][   T45]  ? initrd_load (init/initramfs.c:64)
[    1.516217][   T45]  unpack_to_rootfs (init/initramfs.c:553)
[    1.517220][   T45]  ? write_buffer (init/initramfs.c:476)
[    1.518175][   T45]  ? initrd_load (init/initramfs.c:64)
[    1.519172][   T45]  ? reserve_initrd_mem (init/initramfs.c:719)
[    1.520375][   T45]  do_populate_rootfs (init/initramfs.c:734)
[    1.521401][   T45]  async_run_entry_fn (kernel/async.c:136 (discriminator 1))
[    1.522378][   T45]  ? async_schedule_node (kernel/async.c:118)
[    1.523492][   T45]  process_one_work (arch/x86/include/asm/atomic.h:23 include/linux/atomic/atomic-arch-fallback.h:457 include/linux/jump_label.h:262 include/trace/events/workqueue.h:110 kernel/workqueue.c:3268)
[    1.526446][   T45]  process_scheduled_works (kernel/workqueue.c:3346)
[    1.527578][   T45]  worker_thread (include/linux/list.h:381 (discriminator 2) kernel/workqueue.c:952 (discriminator 2) kernel/workqueue.c:3428 (discriminator 2))
[    1.528573][   T45]  kthread (kernel/kthread.c:465)
[    1.529483][   T45]  ? process_scheduled_works (kernel/workqueue.c:3373)
[    1.530780][   T45]  ? kthread_is_per_cpu (kernel/kthread.c:412)
[    1.531779][   T45]  ret_from_fork (arch/x86/kernel/process.c:164)
[    1.532664][   T45]  ? kthread_is_per_cpu (kernel/kthread.c:412)
[    1.533736][   T45]  ret_from_fork_asm (arch/x86/entry/entry_32.S:737)
[    1.534846][   T45]  entry_INT80_32 (arch/x86/entry/entry_32.S:945)
[    1.536182][   T45] irq event stamp: 2161
[    1.536994][   T45] hardirqs last  enabled at (2161): _raw_spin_unlock_irqrestore (arch/x86/include/asm/irqflags.h:26 arch/x86/include/asm/irqflags.h:109 arch/x86/include/asm/irqflags.h:151 include/linux/spinlock_api_smp.h:151 kernel/locking/spinlock.c:194)
[    1.538763][   T45] hardirqs last disabled at (2160): _raw_spin_lock_irqsave (include/linux/spinlock_api_smp.h:109 kernel/locking/spinlock.c:162)
[    1.540674][   T45] softirqs last  enabled at (1956): handle_softirqs (kernel/softirq.c:469 (discriminator 2) kernel/softirq.c:650 (discriminator 2))
[    1.542454][   T45] softirqs last disabled at (1949): __do_softirq (kernel/softirq.c:657)
[    1.544105][   T45] ---[ end trace 0000000000000000 ]---


The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20251104/202511041421.784bbd5e-lkp@intel.com



-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH v1 21/26] mm: memcontrol: prepare for reparenting LRU pages for lruvec lock
Posted by Qi Zheng 3 months, 1 week ago

On 11/4/25 2:49 PM, kernel test robot wrote:
> 

[...]

> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <oliver.sang@intel.com>
> | Closes: https://lore.kernel.org/oe-lkp/202511041421.784bbd5e-lkp@intel.com
> 
> 
> [    1.392214][   T45] WARNING: bad unlock balance detected!
> [    1.393285][   T45] 6.18.0-rc3-00251-gdd9e066d9677 #1 Not tainted
> [    1.394579][   T45] -------------------------------------
> [    1.395442][   T45] kworker/u9:1/45 is trying to release lock (rcu_read_lock) at:
> [    1.396977][   T45] rcu_read_unlock (include/linux/rcupdate.h:341 include/linux/rcupdate.h:897)
> [    1.398160][   T45] but there are no more locks to release!
> [    1.399337][   T45]
> [    1.399337][   T45] other info that might help us debug this:
> [    1.399707][   T45] 5 locks held by kworker/u9:1/45:
> [    1.399707][   T45]  #0: c01ad6c4 ((wq_completion)async){+.+.}-{0:0}, at: process_one_work (kernel/workqueue.c:3238)
> [    1.399707][   T45]  #1: c08e9f18 ((work_completion)(&entry->work)){+.+.}-{0:0}, at: process_one_work (kernel/workqueue.c:3239)
> [    1.399707][   T45]  #2: c02ed27c (sb_writers#2){.+.+}-{0:0}, at: file_start_write+0x1e/0x30
> [    1.399707][   T45]  #3: c042e0ec (&sb->s_type->i_mutex_key){++++}-{4:4}, at: generic_file_write_iter (mm/filemap.c:4404)
> [    1.399707][   T45]  #4: eaa771a0 (lock#3){+.+.}-{3:3}, at: local_lock_acquire (include/linux/local_lock_internal.h:40)
> [    1.399707][   T45]
> [    1.399707][   T45] stack backtrace:
> [    1.399707][   T45] CPU: 0 UID: 0 PID: 45 Comm: kworker/u9:1 Not tainted 6.18.0-rc3-00251-gdd9e066d9677 #1 PREEMPT(none)
> [    1.399707][   T45] Workqueue: async async_run_entry_fn
> [    1.399707][   T45] Call Trace:
> [    1.399707][   T45]  dump_stack_lvl (lib/dump_stack.c:122)
> [    1.399707][   T45]  ? rcu_read_unlock (include/linux/rcupdate.h:341 include/linux/rcupdate.h:897)
> [    1.399707][   T45]  dump_stack (lib/dump_stack.c:130)
> [    1.399707][   T45]  print_unlock_imbalance_bug (kernel/locking/lockdep.c:5300 kernel/locking/lockdep.c:5272)
> [    1.399707][   T45]  ? rcu_read_unlock (include/linux/rcupdate.h:341 include/linux/rcupdate.h:897)
> [    1.399707][   T45]  __lock_release+0x5e/0x150
> [    1.399707][   T45]  ? rcu_read_unlock (include/linux/rcupdate.h:341 include/linux/rcupdate.h:897)
> [    1.399707][   T45]  lock_release (kernel/locking/lockdep.c:470 kernel/locking/lockdep.c:5891 kernel/locking/lockdep.c:5875)
> [    1.399707][   T45]  ? lru_deactivate_file (mm/swap.c:119)
> [    1.399707][   T45]  rcu_read_unlock (include/linux/rcupdate.h:899)
> [    1.399707][   T45]  lruvec_unlock_irqrestore (include/linux/memcontrol.h:1522)
> [    1.399707][   T45]  folio_batch_move_lru (include/linux/mm.h:1501 mm/swap.c:179)
> [    1.399707][   T45]  __folio_batch_add_and_move (mm/swap.c:196 (discriminator 2))
> [    1.399707][   T45]  ? lru_deactivate_file (mm/swap.c:119)
> [    1.399707][   T45]  folio_add_lru (mm/swap.c:514)
> [    1.399707][   T45]  filemap_add_folio (mm/filemap.c:996)
> [    1.399707][   T45]  __filemap_get_folio (mm/filemap.c:2023)
> [    1.399707][   T45]  simple_write_begin (fs/libfs.c:932 (discriminator 1))
> [    1.399707][   T45]  generic_perform_write (mm/filemap.c:4263)
> [    1.399707][   T45]  __generic_file_write_iter (mm/filemap.c:4380)
> [    1.399707][   T45]  generic_file_write_iter (mm/filemap.c:4406)
> [    1.399707][   T45]  __kernel_write_iter (fs/read_write.c:619)
> [    1.399707][   T45]  __kernel_write (fs/read_write.c:640)
> [    1.399707][   T45]  kernel_write (fs/read_write.c:660 fs/read_write.c:650)
> [    1.399707][   T45]  xwrite+0x27/0x80
> [    1.399707][   T45]  do_copy (init/initramfs.c:417 (discriminator 1))
> [    1.399707][   T45]  write_buffer (init/initramfs.c:470 (discriminator 1))
> [    1.399707][   T45]  flush_buffer (init/initramfs.c:482 (discriminator 1))
> [    1.399707][   T45]  __gunzip+0x21d/0x2c0
> [    1.399707][   T45]  ? bunzip2 (lib/decompress_inflate.c:39)
> [    1.399707][   T45]  ? __gunzip+0x2c0/0x2c0
> [    1.399707][   T45]  gunzip (lib/decompress_inflate.c:208)
> [    1.399707][   T45]  ? write_buffer (init/initramfs.c:476)
> [    1.399707][   T45]  ? initrd_load (init/initramfs.c:64)
> [    1.399707][   T45]  unpack_to_rootfs (init/initramfs.c:553)
> [    1.399707][   T45]  ? write_buffer (init/initramfs.c:476)
> [    1.399707][   T45]  ? initrd_load (init/initramfs.c:64)
> [    1.399707][   T45]  ? reserve_initrd_mem (init/initramfs.c:719)
> [    1.399707][   T45]  do_populate_rootfs (init/initramfs.c:734)
> [    1.399707][   T45]  async_run_entry_fn (kernel/async.c:136 (discriminator 1))
> [    1.399707][   T45]  ? async_schedule_node (kernel/async.c:118)
> [    1.399707][   T45]  process_one_work (arch/x86/include/asm/atomic.h:23 include/linux/atomic/atomic-arch-fallback.h:457 include/linux/jump_label.h:262 include/trace/events/workqueue.h:110 kernel/workqueue.c:3268)
> [    1.399707][   T45]  process_scheduled_works (kernel/workqueue.c:3346)
> [    1.399707][   T45]  worker_thread (include/linux/list.h:381 (discriminator 2) kernel/workqueue.c:952 (discriminator 2) kernel/workqueue.c:3428 (discriminator 2))
> [    1.399707][   T45]  kthread (kernel/kthread.c:465)
> [    1.399707][   T45]  ? process_scheduled_works (kernel/workqueue.c:3373)
> [    1.399707][   T45]  ? kthread_is_per_cpu (kernel/kthread.c:412)
> [    1.399707][   T45]  ret_from_fork (arch/x86/kernel/process.c:164)
> [    1.399707][   T45]  ? kthread_is_per_cpu (kernel/kthread.c:412)
> [    1.399707][   T45]  ret_from_fork_asm (arch/x86/entry/entry_32.S:737)
> [    1.399707][   T45]  entry_INT80_32 (arch/x86/entry/entry_32.S:945)
> [    1.467118][   T32] Callback from call_rcu_tasks() invoked.
> [    1.468370][   T45] ------------[ cut here ]------------
> [    1.469508][   T45] WARNING: CPU: 0 PID: 45 at kernel/rcu/tree_plugin.h:443 __rcu_read_unlock (kernel/rcu/tree_plugin.h:443)
> [    1.471711][   T45] Modules linked in:
> [    1.472490][   T45] CPU: 0 UID: 0 PID: 45 Comm: kworker/u9:1 Not tainted 6.18.0-rc3-00251-gdd9e066d9677 #1 PREEMPT(none)
> [    1.474777][   T45] Workqueue: async async_run_entry_fn
> [    1.475823][   T45] EIP: __rcu_read_unlock (kernel/rcu/tree_plugin.h:443)
> [    1.476872][   T45] Code: 0c d0 56 c2 ff 8b a4 02 00 00 75 11 8b 83 a8 02 00 00 85 c0 74 07 89 d8 e8 7c fe ff ff 8b 83 a4 02 00 00 3d ff ff ff 3f 76 02 <0f> 0b 5b 5d 31 c0 c3 2e 8d b4 26 00 00 00 00 55 89 e5 57 56 89 c6
> All code
> ========
>     0:	0c d0                	or     $0xd0,%al
>     2:	56                   	push   %rsi
>     3:	c2 ff 8b             	ret    $0x8bff
>     6:	a4                   	movsb  %ds:(%rsi),%es:(%rdi)
>     7:	02 00                	add    (%rax),%al
>     9:	00 75 11             	add    %dh,0x11(%rbp)
>     c:	8b 83 a8 02 00 00    	mov    0x2a8(%rbx),%eax
>    12:	85 c0                	test   %eax,%eax
>    14:	74 07                	je     0x1d
>    16:	89 d8                	mov    %ebx,%eax
>    18:	e8 7c fe ff ff       	call   0xfffffffffffffe99
>    1d:	8b 83 a4 02 00 00    	mov    0x2a4(%rbx),%eax
>    23:	3d ff ff ff 3f       	cmp    $0x3fffffff,%eax
>    28:	76 02                	jbe    0x2c
>    2a:*	0f 0b                	ud2		<-- trapping instruction
>    2c:	5b                   	pop    %rbx
>    2d:	5d                   	pop    %rbp
>    2e:	31 c0                	xor    %eax,%eax
>    30:	c3                   	ret
>    31:	2e 8d b4 26 00 00 00 	cs lea 0x0(%rsi,%riz,1),%esi
>    38:	00
>    39:	55                   	push   %rbp
>    3a:	89 e5                	mov    %esp,%ebp
>    3c:	57                   	push   %rdi
>    3d:	56                   	push   %rsi
>    3e:	89 c6                	mov    %eax,%esi
> 
> Code starting with the faulting instruction
> ===========================================
>     0:	0f 0b                	ud2
>     2:	5b                   	pop    %rbx
>     3:	5d                   	pop    %rbp
>     4:	31 c0                	xor    %eax,%eax
>     6:	c3                   	ret
>     7:	2e 8d b4 26 00 00 00 	cs lea 0x0(%rsi,%riz,1),%esi
>     e:	00
>     f:	55                   	push   %rbp
>    10:	89 e5                	mov    %esp,%ebp
>    12:	57                   	push   %rdi
>    13:	56                   	push   %rsi
>    14:	89 c6                	mov    %eax,%esi
> [    1.480862][   T45] EAX: ffffffff EBX: c0bfd640 ECX: 00000000 EDX: 00000000
> [    1.482292][   T45] ESI: eaa771c0 EDI: c119e160 EBP: c08e9c0c ESP: c08e9c08
> [    1.483721][   T45] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 EFLAGS: 00010286
> [    1.485350][   T45] CR0: 80050033 CR2: ffbff000 CR3: 026c6000 CR4: 000006f0
> [    1.486725][   T45] Call Trace:
> [    1.487465][   T45]  rcu_read_unlock (include/linux/rcupdate.h:900)
> [    1.488404][   T45]  lruvec_unlock_irqrestore (include/linux/memcontrol.h:1522)
> [    1.489570][   T45]  folio_batch_move_lru (include/linux/mm.h:1501 mm/swap.c:179)
> [    1.491100][   T45]  __folio_batch_add_and_move (mm/swap.c:196 (discriminator 2))
> [    1.492318][   T45]  ? lru_deactivate_file (mm/swap.c:119)
> [    1.493827][   T45]  folio_add_lru (mm/swap.c:514)
> [    1.494817][   T45]  filemap_add_folio (mm/filemap.c:996)
> [    1.495891][   T45]  __filemap_get_folio (mm/filemap.c:2023)
> [    1.497735][   T45]  simple_write_begin (fs/libfs.c:932 (discriminator 1))
> [    1.498813][   T45]  generic_perform_write (mm/filemap.c:4263)
> [    1.500292][   T45]  __generic_file_write_iter (mm/filemap.c:4380)
> [    1.501552][   T45]  generic_file_write_iter (mm/filemap.c:4406)
> [    1.502790][   T45]  __kernel_write_iter (fs/read_write.c:619)
> [    1.504090][   T45]  __kernel_write (fs/read_write.c:640)
> [    1.505377][   T45]  kernel_write (fs/read_write.c:660 fs/read_write.c:650)
> [    1.506306][   T45]  xwrite+0x27/0x80
> [    1.507429][   T45]  do_copy (init/initramfs.c:417 (discriminator 1))
> [    1.508361][   T45]  write_buffer (init/initramfs.c:470 (discriminator 1))
> [    1.509300][   T45]  flush_buffer (init/initramfs.c:482 (discriminator 1))
> [    1.510307][   T45]  __gunzip+0x21d/0x2c0
> [    1.511424][   T45]  ? bunzip2 (lib/decompress_inflate.c:39)
> [    1.512312][   T45]  ? __gunzip+0x2c0/0x2c0
> [    1.513515][   T45]  gunzip (lib/decompress_inflate.c:208)
> [    1.514359][   T45]  ? write_buffer (init/initramfs.c:476)
> [    1.515304][   T45]  ? initrd_load (init/initramfs.c:64)
> [    1.516217][   T45]  unpack_to_rootfs (init/initramfs.c:553)
> [    1.517220][   T45]  ? write_buffer (init/initramfs.c:476)
> [    1.518175][   T45]  ? initrd_load (init/initramfs.c:64)
> [    1.519172][   T45]  ? reserve_initrd_mem (init/initramfs.c:719)
> [    1.520375][   T45]  do_populate_rootfs (init/initramfs.c:734)
> [    1.521401][   T45]  async_run_entry_fn (kernel/async.c:136 (discriminator 1))
> [    1.522378][   T45]  ? async_schedule_node (kernel/async.c:118)
> [    1.523492][   T45]  process_one_work (arch/x86/include/asm/atomic.h:23 include/linux/atomic/atomic-arch-fallback.h:457 include/linux/jump_label.h:262 include/trace/events/workqueue.h:110 kernel/workqueue.c:3268)
> [    1.526446][   T45]  process_scheduled_works (kernel/workqueue.c:3346)
> [    1.527578][   T45]  worker_thread (include/linux/list.h:381 (discriminator 2) kernel/workqueue.c:952 (discriminator 2) kernel/workqueue.c:3428 (discriminator 2))
> [    1.528573][   T45]  kthread (kernel/kthread.c:465)
> [    1.529483][   T45]  ? process_scheduled_works (kernel/workqueue.c:3373)
> [    1.530780][   T45]  ? kthread_is_per_cpu (kernel/kthread.c:412)
> [    1.531779][   T45]  ret_from_fork (arch/x86/kernel/process.c:164)
> [    1.532664][   T45]  ? kthread_is_per_cpu (kernel/kthread.c:412)
> [    1.533736][   T45]  ret_from_fork_asm (arch/x86/entry/entry_32.S:737)
> [    1.534846][   T45]  entry_INT80_32 (arch/x86/entry/entry_32.S:945)
> [    1.536182][   T45] irq event stamp: 2161
> [    1.536994][   T45] hardirqs last  enabled at (2161): _raw_spin_unlock_irqrestore (arch/x86/include/asm/irqflags.h:26 arch/x86/include/asm/irqflags.h:109 arch/x86/include/asm/irqflags.h:151 include/linux/spinlock_api_smp.h:151 kernel/locking/spinlock.c:194)
> [    1.538763][   T45] hardirqs last disabled at (2160): _raw_spin_lock_irqsave (include/linux/spinlock_api_smp.h:109 kernel/locking/spinlock.c:162)
> [    1.540674][   T45] softirqs last  enabled at (1956): handle_softirqs (kernel/softirq.c:469 (discriminator 2) kernel/softirq.c:650 (discriminator 2))
> [    1.542454][   T45] softirqs last disabled at (1949): __do_softirq (kernel/softirq.c:657)
> [    1.544105][   T45] ---[ end trace 0000000000000000 ]---
> 
> 
> The kernel config and materials to reproduce are available at:
> https://download.01.org/0day-ci/archive/20251104/202511041421.784bbd5e-lkp@intel.com

In this config file, CONFIG_MEMCG is not set:

# CONFIG_MEMCG is not set

In this case, folio_lruvec_lock*() was not modified (add
rcu_read_lock()), will fix it in the next version.

Thanks,
Qi

> 
> 
>