Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

cpuset: separate tmpmasks and cpuset allocation logic

The original alloc_cpumasks() served dual purposes: allocating cpumasks
for both temporary masks (tmpmasks) and cpuset structures. This patch:

1. Decouples these allocation paths for better code clarity
2. Introduces dedicated alloc_tmpmasks() and dup_or_alloc_cpuset()
functions
3. Maintains symmetric pairing:
- alloc_tmpmasks() ↔ free_tmpmasks()
- dup_or_alloc_cpuset() ↔ free_cpuset()

Signed-off-by: Chen Ridong <chenridong@huawei.com>
Reviewed-by: Waiman Long <longman@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>

authored by

Chen Ridong and committed by
Tejun Heo
ada00d51 5806b3d0

+69 -58
+69 -58
kernel/cgroup/cpuset.c
··· 411 411 } 412 412 413 413 /** 414 - * alloc_cpumasks - allocate three cpumasks for cpuset 415 - * @cs: the cpuset that have cpumasks to be allocated. 416 - * @tmp: the tmpmasks structure pointer 414 + * alloc_cpumasks - Allocate an array of cpumask variables 415 + * @pmasks: Pointer to array of cpumask_var_t pointers 416 + * @size: Number of cpumasks to allocate 417 417 * Return: 0 if successful, -ENOMEM otherwise. 418 418 * 419 - * Only one of the two input arguments should be non-NULL. 419 + * Allocates @size cpumasks and initializes them to empty. Returns 0 on 420 + * success, -ENOMEM on allocation failure. On failure, any previously 421 + * allocated cpumasks are freed. 420 422 */ 421 - static inline int alloc_cpumasks(struct cpuset *cs, struct tmpmasks *tmp) 423 + static inline int alloc_cpumasks(cpumask_var_t *pmasks[], u32 size) 422 424 { 423 - cpumask_var_t *pmask1, *pmask2, *pmask3, *pmask4; 425 + int i; 424 426 425 - if (cs) { 426 - pmask1 = &cs->cpus_allowed; 427 - pmask2 = &cs->effective_cpus; 428 - pmask3 = &cs->effective_xcpus; 429 - pmask4 = &cs->exclusive_cpus; 430 - } else { 431 - pmask1 = &tmp->new_cpus; 432 - pmask2 = &tmp->addmask; 433 - pmask3 = &tmp->delmask; 434 - pmask4 = NULL; 427 + for (i = 0; i < size; i++) { 428 + if (!zalloc_cpumask_var(pmasks[i], GFP_KERNEL)) { 429 + while (--i >= 0) 430 + free_cpumask_var(*pmasks[i]); 431 + return -ENOMEM; 432 + } 435 433 } 436 - 437 - if (!zalloc_cpumask_var(pmask1, GFP_KERNEL)) 438 - return -ENOMEM; 439 - 440 - if (!zalloc_cpumask_var(pmask2, GFP_KERNEL)) 441 - goto free_one; 442 - 443 - if (!zalloc_cpumask_var(pmask3, GFP_KERNEL)) 444 - goto free_two; 445 - 446 - if (pmask4 && !zalloc_cpumask_var(pmask4, GFP_KERNEL)) 447 - goto free_three; 448 - 449 - 450 434 return 0; 435 + } 451 436 452 - free_three: 453 - free_cpumask_var(*pmask3); 454 - free_two: 455 - free_cpumask_var(*pmask2); 456 - free_one: 457 - free_cpumask_var(*pmask1); 458 - return -ENOMEM; 437 + /** 438 + * alloc_tmpmasks - Allocate temporary cpumasks for cpuset operations. 439 + * @tmp: Pointer to tmpmasks structure to populate 440 + * Return: 0 on success, -ENOMEM on allocation failure 441 + */ 442 + static inline int alloc_tmpmasks(struct tmpmasks *tmp) 443 + { 444 + /* 445 + * Array of pointers to the three cpumask_var_t fields in tmpmasks. 446 + * Note: Array size must match actual number of masks (3) 447 + */ 448 + cpumask_var_t *pmask[3] = { 449 + &tmp->new_cpus, 450 + &tmp->addmask, 451 + &tmp->delmask 452 + }; 453 + 454 + return alloc_cpumasks(pmask, ARRAY_SIZE(pmask)); 459 455 } 460 456 461 457 /** ··· 466 470 } 467 471 468 472 /** 469 - * alloc_trial_cpuset - allocate a trial cpuset 470 - * @cs: the cpuset that the trial cpuset duplicates 473 + * dup_or_alloc_cpuset - Duplicate or allocate a new cpuset 474 + * @cs: Source cpuset to duplicate (NULL for a fresh allocation) 475 + * 476 + * Creates a new cpuset by either: 477 + * 1. Duplicating an existing cpuset (if @cs is non-NULL), or 478 + * 2. Allocating a fresh cpuset with zero-initialized masks (if @cs is NULL) 479 + * 480 + * Return: Pointer to newly allocated cpuset on success, NULL on failure 471 481 */ 472 - static struct cpuset *alloc_trial_cpuset(struct cpuset *cs) 482 + static struct cpuset *dup_or_alloc_cpuset(struct cpuset *cs) 473 483 { 474 484 struct cpuset *trial; 475 485 476 - trial = kmemdup(cs, sizeof(*cs), GFP_KERNEL); 486 + /* Allocate base structure */ 487 + trial = cs ? kmemdup(cs, sizeof(*cs), GFP_KERNEL) : 488 + kzalloc(sizeof(*cs), GFP_KERNEL); 477 489 if (!trial) 478 490 return NULL; 479 491 480 - if (alloc_cpumasks(trial, NULL)) { 492 + /* Setup cpumask pointer array */ 493 + cpumask_var_t *pmask[4] = { 494 + &trial->cpus_allowed, 495 + &trial->effective_cpus, 496 + &trial->effective_xcpus, 497 + &trial->exclusive_cpus 498 + }; 499 + 500 + if (alloc_cpumasks(pmask, ARRAY_SIZE(pmask))) { 481 501 kfree(trial); 482 502 return NULL; 483 503 } 484 504 485 - cpumask_copy(trial->cpus_allowed, cs->cpus_allowed); 486 - cpumask_copy(trial->effective_cpus, cs->effective_cpus); 487 - cpumask_copy(trial->effective_xcpus, cs->effective_xcpus); 488 - cpumask_copy(trial->exclusive_cpus, cs->exclusive_cpus); 505 + /* Copy masks if duplicating */ 506 + if (cs) { 507 + cpumask_copy(trial->cpus_allowed, cs->cpus_allowed); 508 + cpumask_copy(trial->effective_cpus, cs->effective_cpus); 509 + cpumask_copy(trial->effective_xcpus, cs->effective_xcpus); 510 + cpumask_copy(trial->exclusive_cpus, cs->exclusive_cpus); 511 + } 512 + 489 513 return trial; 490 514 } 491 515 ··· 2348 2332 if (cpumask_equal(cs->cpus_allowed, trialcs->cpus_allowed)) 2349 2333 return 0; 2350 2334 2351 - if (alloc_cpumasks(NULL, &tmp)) 2335 + if (alloc_tmpmasks(&tmp)) 2352 2336 return -ENOMEM; 2353 2337 2354 2338 if (old_prs) { ··· 2492 2476 if (retval) 2493 2477 return retval; 2494 2478 2495 - if (alloc_cpumasks(NULL, &tmp)) 2479 + if (alloc_tmpmasks(&tmp)) 2496 2480 return -ENOMEM; 2497 2481 2498 2482 if (old_prs) { ··· 2836 2820 int spread_flag_changed; 2837 2821 int err; 2838 2822 2839 - trialcs = alloc_trial_cpuset(cs); 2823 + trialcs = dup_or_alloc_cpuset(cs); 2840 2824 if (!trialcs) 2841 2825 return -ENOMEM; 2842 2826 ··· 2897 2881 if (new_prs && is_prs_invalid(old_prs)) 2898 2882 old_prs = PRS_MEMBER; 2899 2883 2900 - if (alloc_cpumasks(NULL, &tmpmask)) 2884 + if (alloc_tmpmasks(&tmpmask)) 2901 2885 return -ENOMEM; 2902 2886 2903 2887 err = update_partition_exclusive_flag(cs, new_prs); ··· 3239 3223 if (!is_cpuset_online(cs)) 3240 3224 goto out_unlock; 3241 3225 3242 - trialcs = alloc_trial_cpuset(cs); 3226 + trialcs = dup_or_alloc_cpuset(cs); 3243 3227 if (!trialcs) { 3244 3228 retval = -ENOMEM; 3245 3229 goto out_unlock; ··· 3472 3456 if (!parent_css) 3473 3457 return &top_cpuset.css; 3474 3458 3475 - cs = kzalloc(sizeof(*cs), GFP_KERNEL); 3459 + cs = dup_or_alloc_cpuset(NULL); 3476 3460 if (!cs) 3477 3461 return ERR_PTR(-ENOMEM); 3478 - 3479 - if (alloc_cpumasks(cs, NULL)) { 3480 - kfree(cs); 3481 - return ERR_PTR(-ENOMEM); 3482 - } 3483 3462 3484 3463 __set_bit(CS_SCHED_LOAD_BALANCE, &cs->flags); 3485 3464 fmeter_init(&cs->fmeter); ··· 3931 3920 bool on_dfl = is_in_v2_mode(); 3932 3921 struct tmpmasks tmp, *ptmp = NULL; 3933 3922 3934 - if (on_dfl && !alloc_cpumasks(NULL, &tmp)) 3923 + if (on_dfl && !alloc_tmpmasks(&tmp)) 3935 3924 ptmp = &tmp; 3936 3925 3937 3926 lockdep_assert_cpus_held();