All of lore.kernel.org
 help / color / mirror / Atom feed
From: kernel test robot <lkp@intel.com>
To: Hui Zhu <hui.zhu@linux.dev>
Cc: llvm@lists.linux.dev, oe-kbuild-all@lists.linux.dev
Subject: Re: [RFC PATCH 1/3] memcg: add eBPF struct ops support for memory charging
Date: Sat, 22 Nov 2025 03:24:13 +0800	[thread overview]
Message-ID: <202511220227.thU6cgqc-lkp@intel.com> (raw)
In-Reply-To: <15f95166c6c516f303f3092e74c88ace5164bdf0.1763457705.git.zhuhui@kylinos.cn>

Hi Hui,

[This is a private test report for your RFC patch.]
kernel test robot noticed the following build errors:

[auto build test ERROR on bpf-next/net]
[also build test ERROR on bpf-next/master bpf/master linus/master v6.18-rc6 next-20251121]
[cannot apply to akpm-mm/mm-everything]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Hui-Zhu/memcg-add-eBPF-struct-ops-support-for-memory-charging/20251119-093645
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git net
patch link:    https://lore.kernel.org/r/15f95166c6c516f303f3092e74c88ace5164bdf0.1763457705.git.zhuhui%40kylinos.cn
patch subject: [RFC PATCH 1/3] memcg: add eBPF struct ops support for memory charging
config: hexagon-randconfig-001-20251121 (https://download.01.org/0day-ci/archive/20251122/202511220227.thU6cgqc-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 9e9fe08b16ea2c4d9867fb4974edf2a3776d6ece)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251122/202511220227.thU6cgqc-lkp@intel.com/reproduce)

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 <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511220227.thU6cgqc-lkp@intel.com/

All errors (new ones prefixed by >>):

>> mm/memcontrol.c:2341:14: error: assigning to 'unsigned long' from incompatible type 'void'
    2341 |         nr_reclaime = bpf_try_charge_memcg(memcg, gfp_mask, nr_pages,
         |                     ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    2342 |                                            mem_over_limit,
         |                                            ~~~~~~~~~~~~~~~
    2343 |                                            reclaim_options,
         |                                            ~~~~~~~~~~~~~~~~
    2344 |                                            charge_done);
         |                                            ~~~~~~~~~~~~
   1 error generated.


vim +2341 mm/memcontrol.c

  2297	
  2298	static int try_charge_memcg(struct mem_cgroup *memcg, gfp_t gfp_mask,
  2299				    unsigned int nr_pages)
  2300	{
  2301		unsigned int batch = max(MEMCG_CHARGE_BATCH, nr_pages);
  2302		int nr_retries = MAX_RECLAIM_RETRIES;
  2303		struct mem_cgroup *mem_over_limit;
  2304		struct page_counter *counter;
  2305		unsigned long nr_reclaime, nr_reclaimed;
  2306		bool passed_oom = false;
  2307		unsigned int reclaim_options = MEMCG_RECLAIM_MAY_SWAP;
  2308		bool drained = false;
  2309		bool raised_max_event = false;
  2310		unsigned long pflags;
  2311		bool allow_spinning = gfpflags_allow_spinning(gfp_mask);
  2312		bool charge_done = false;
  2313	
  2314	retry:
  2315		if (consume_stock(memcg, nr_pages))
  2316			return 0;
  2317	
  2318		if (!allow_spinning)
  2319			/* Avoid the refill and flush of the older stock */
  2320			batch = nr_pages;
  2321	
  2322		if (!do_memsw_account() ||
  2323		    page_counter_try_charge(&memcg->memsw, batch, &counter)) {
  2324			if (page_counter_try_charge(&memcg->memory, batch, &counter))
  2325				charge_done = true;
  2326			else {
  2327				if (do_memsw_account())
  2328					page_counter_uncharge(&memcg->memsw, batch);
  2329				mem_over_limit = mem_cgroup_from_counter(counter, memory);
  2330			}
  2331		} else {
  2332			mem_over_limit = mem_cgroup_from_counter(counter, memsw);
  2333			reclaim_options &= ~MEMCG_RECLAIM_MAY_SWAP;
  2334		}
  2335	
  2336		if (!charge_done && batch > nr_pages) {
  2337			batch = nr_pages;
  2338			goto retry;
  2339		}
  2340	
> 2341		nr_reclaime = bpf_try_charge_memcg(memcg, gfp_mask, nr_pages,
  2342						   mem_over_limit,
  2343						   reclaim_options,
  2344						   charge_done);
  2345	
  2346		if (charge_done)
  2347			goto done_restock;
  2348	
  2349		/*
  2350		 * Prevent unbounded recursion when reclaim operations need to
  2351		 * allocate memory. This might exceed the limits temporarily,
  2352		 * but we prefer facilitating memory reclaim and getting back
  2353		 * under the limit over triggering OOM kills in these cases.
  2354		 */
  2355		if (unlikely(current->flags & PF_MEMALLOC))
  2356			goto force;
  2357	
  2358		if (unlikely(task_in_memcg_oom(current)))
  2359			goto nomem;
  2360	
  2361		if (!gfpflags_allow_blocking(gfp_mask))
  2362			goto nomem;
  2363	
  2364		__memcg_memory_event(mem_over_limit, MEMCG_MAX, allow_spinning);
  2365		raised_max_event = true;
  2366	
  2367		psi_memstall_enter(&pflags);
  2368		nr_reclaimed = try_to_free_mem_cgroup_pages(mem_over_limit, nr_reclaime,
  2369							    gfp_mask, reclaim_options, NULL);
  2370		psi_memstall_leave(&pflags);
  2371	
  2372		if (mem_cgroup_margin(mem_over_limit) >= nr_pages)
  2373			goto retry;
  2374	
  2375		if (!drained) {
  2376			drain_all_stock(mem_over_limit);
  2377			drained = true;
  2378			goto retry;
  2379		}
  2380	
  2381		if (gfp_mask & __GFP_NORETRY)
  2382			goto nomem;
  2383		/*
  2384		 * Even though the limit is exceeded at this point, reclaim
  2385		 * may have been able to free some pages.  Retry the charge
  2386		 * before killing the task.
  2387		 *
  2388		 * Only for regular pages, though: huge pages are rather
  2389		 * unlikely to succeed so close to the limit, and we fall back
  2390		 * to regular pages anyway in case of failure.
  2391		 */
  2392		if (nr_reclaimed && nr_pages <= (1 << PAGE_ALLOC_COSTLY_ORDER))
  2393			goto retry;
  2394	
  2395		if (nr_retries--)
  2396			goto retry;
  2397	
  2398		if (gfp_mask & __GFP_RETRY_MAYFAIL)
  2399			goto nomem;
  2400	
  2401		/* Avoid endless loop for tasks bypassed by the oom killer */
  2402		if (passed_oom && task_is_dying())
  2403			goto nomem;
  2404	
  2405		/*
  2406		 * keep retrying as long as the memcg oom killer is able to make
  2407		 * a forward progress or bypass the charge if the oom killer
  2408		 * couldn't make any progress.
  2409		 */
  2410		if (mem_cgroup_oom(mem_over_limit, gfp_mask,
  2411				   get_order(nr_pages * PAGE_SIZE))) {
  2412			passed_oom = true;
  2413			nr_retries = MAX_RECLAIM_RETRIES;
  2414			goto retry;
  2415		}
  2416	nomem:
  2417		/*
  2418		 * Memcg doesn't have a dedicated reserve for atomic
  2419		 * allocations. But like the global atomic pool, we need to
  2420		 * put the burden of reclaim on regular allocation requests
  2421		 * and let these go through as privileged allocations.
  2422		 */
  2423		if (!(gfp_mask & (__GFP_NOFAIL | __GFP_HIGH)))
  2424			return -ENOMEM;
  2425	force:
  2426		/*
  2427		 * If the allocation has to be enforced, don't forget to raise
  2428		 * a MEMCG_MAX event.
  2429		 */
  2430		if (!raised_max_event)
  2431			__memcg_memory_event(mem_over_limit, MEMCG_MAX, allow_spinning);
  2432	
  2433		/*
  2434		 * The allocation either can't fail or will lead to more memory
  2435		 * being freed very soon.  Allow memory usage go over the limit
  2436		 * temporarily by force charging it.
  2437		 */
  2438		page_counter_charge(&memcg->memory, nr_pages);
  2439		if (do_memsw_account())
  2440			page_counter_charge(&memcg->memsw, nr_pages);
  2441	
  2442		return 0;
  2443	
  2444	done_restock:
  2445		if (batch > nr_pages)
  2446			refill_stock(memcg, batch - nr_pages);
  2447	
  2448		/*
  2449		 * If the hierarchy is above the normal consumption range, schedule
  2450		 * reclaim on returning to userland.  We can perform reclaim here
  2451		 * if __GFP_RECLAIM but let's always punt for simplicity and so that
  2452		 * GFP_KERNEL can consistently be used during reclaim.  @memcg is
  2453		 * not recorded as it most likely matches current's and won't
  2454		 * change in the meantime.  As high limit is checked again before
  2455		 * reclaim, the cost of mismatch is negligible.
  2456		 */
  2457		do {
  2458			bool mem_high, swap_high;
  2459	
  2460			mem_high = page_counter_read(&memcg->memory) >
  2461				READ_ONCE(memcg->memory.high);
  2462			swap_high = page_counter_read(&memcg->swap) >
  2463				READ_ONCE(memcg->swap.high);
  2464	
  2465			/* Don't bother a random interrupted task */
  2466			if (!in_task()) {
  2467				if (mem_high) {
  2468					schedule_work(&memcg->high_work);
  2469					break;
  2470				}
  2471				continue;
  2472			}
  2473	
  2474			if (mem_high || swap_high) {
  2475				/*
  2476				 * The allocating tasks in this cgroup will need to do
  2477				 * reclaim or be throttled to prevent further growth
  2478				 * of the memory or swap footprints.
  2479				 *
  2480				 * Target some best-effort fairness between the tasks,
  2481				 * and distribute reclaim work and delay penalties
  2482				 * based on how much each task is actually allocating.
  2483				 */
  2484				current->memcg_nr_pages_over_high += batch;
  2485				set_notify_resume(current);
  2486				break;
  2487			}
  2488		} while ((memcg = parent_mem_cgroup(memcg)));
  2489	
  2490		/*
  2491		 * Reclaim is set up above to be called from the userland
  2492		 * return path. But also attempt synchronous reclaim to avoid
  2493		 * excessive overrun while the task is still inside the
  2494		 * kernel. If this is successful, the return path will see it
  2495		 * when it rechecks the overage and simply bail out.
  2496		 */
  2497		if (current->memcg_nr_pages_over_high > MEMCG_CHARGE_BATCH &&
  2498		    !(current->flags & PF_MEMALLOC) &&
  2499		    gfpflags_allow_blocking(gfp_mask))
  2500			__mem_cgroup_handle_over_high(gfp_mask);
  2501		return 0;
  2502	}
  2503	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

  parent reply	other threads:[~2025-11-21 19:24 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-19  1:34 [RFC PATCH 0/3] Memory Controller eBPF support Hui Zhu
2025-11-19  1:34 ` [RFC PATCH 1/3] memcg: add eBPF struct ops support for memory charging Hui Zhu
2025-11-19  2:10   ` bot+bpf-ci
2025-11-19 16:07   ` Tejun Heo
2025-11-21 19:24   ` kernel test robot [this message]
2025-11-19  1:34 ` [RFC PATCH 2/3] selftests/bpf: add memcg eBPF struct ops test Hui Zhu
2025-11-19  2:19   ` bot+bpf-ci
2025-11-19  1:34 ` [RFC PATCH 3/3] samples/bpf: add example memcg eBPF program Hui Zhu
2025-11-19  2:19   ` bot+bpf-ci
2025-11-20  3:04 ` [RFC PATCH 0/3] Memory Controller eBPF support Roman Gushchin
2025-11-20  9:29   ` hui.zhu
2025-11-20 19:20     ` Michal Hocko
2025-11-21  2:46       ` hui.zhu
2025-11-25 12:12         ` Michal Hocko
2025-11-25 12:39           ` hui.zhu
2025-11-25 12:55             ` Michal Hocko
2025-11-26  3:05               ` hui.zhu
2025-11-26 16:01                 ` Michal Hocko
2025-11-27  8:51                   ` hui.zhu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=202511220227.thU6cgqc-lkp@intel.com \
    --to=lkp@intel.com \
    --cc=hui.zhu@linux.dev \
    --cc=llvm@lists.linux.dev \
    --cc=oe-kbuild-all@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.