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.

mm/khugepaged: remove definition of struct khugepaged_mm_slot

Current code is not correct to get struct khugepaged_mm_slot by
mm_slot_entry() without checking mm_slot is !NULL. There is no problem
reported since slot is the first element of struct khugepaged_mm_slot.

While struct khugepaged_mm_slot is just a wrapper of struct mm_slot, there
is no need to define it.

Remove the definition of struct khugepaged_mm_slot, so there is not chance
to miss use mm_slot_entry().

[richard.weiyang@gmail.com: fix use-after-free crash]
Link: https://lkml.kernel.org/r/20250922002834.vz6ntj36e75ehkyp@master
Link: https://lkml.kernel.org/r/20250919071244.17020-3-richard.weiyang@gmail.com
Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: David Hildenbrand <david@redhat.com>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Kiryl Shutsemau <kirill@shutemov.name>
Cc: xu xin <xu.xin16@zte.com.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Wei Yang and committed by
Andrew Morton
b4c9ffb5 08498be4

+21 -37
+21 -37
mm/khugepaged.c
··· 104 104 }; 105 105 106 106 /** 107 - * struct khugepaged_mm_slot - khugepaged information per mm that is being scanned 108 - * @slot: hash lookup from mm to mm_slot 109 - */ 110 - struct khugepaged_mm_slot { 111 - struct mm_slot slot; 112 - }; 113 - 114 - /** 115 107 * struct khugepaged_scan - cursor for scanning 116 108 * @mm_head: the head of the mm list to scan 117 109 * @mm_slot: the current mm_slot we are scanning ··· 113 121 */ 114 122 struct khugepaged_scan { 115 123 struct list_head mm_head; 116 - struct khugepaged_mm_slot *mm_slot; 124 + struct mm_slot *mm_slot; 117 125 unsigned long address; 118 126 }; 119 127 ··· 376 384 377 385 int __init khugepaged_init(void) 378 386 { 379 - mm_slot_cache = KMEM_CACHE(khugepaged_mm_slot, 0); 387 + mm_slot_cache = kmem_cache_create("khugepaged_mm_slot", 388 + sizeof(struct mm_slot), 389 + __alignof__(struct mm_slot), 390 + 0, NULL); 380 391 if (!mm_slot_cache) 381 392 return -ENOMEM; 382 393 ··· 433 438 434 439 void __khugepaged_enter(struct mm_struct *mm) 435 440 { 436 - struct khugepaged_mm_slot *mm_slot; 437 441 struct mm_slot *slot; 438 442 int wakeup; 439 443 ··· 441 447 if (unlikely(mm_flags_test_and_set(MMF_VM_HUGEPAGE, mm))) 442 448 return; 443 449 444 - mm_slot = mm_slot_alloc(mm_slot_cache); 445 - if (!mm_slot) 450 + slot = mm_slot_alloc(mm_slot_cache); 451 + if (!slot) 446 452 return; 447 - 448 - slot = &mm_slot->slot; 449 453 450 454 spin_lock(&khugepaged_mm_lock); 451 455 mm_slot_insert(mm_slots_hash, mm, slot); ··· 472 480 473 481 void __khugepaged_exit(struct mm_struct *mm) 474 482 { 475 - struct khugepaged_mm_slot *mm_slot; 476 483 struct mm_slot *slot; 477 484 int free = 0; 478 485 479 486 spin_lock(&khugepaged_mm_lock); 480 487 slot = mm_slot_lookup(mm_slots_hash, mm); 481 - mm_slot = mm_slot_entry(slot, struct khugepaged_mm_slot, slot); 482 - if (mm_slot && khugepaged_scan.mm_slot != mm_slot) { 488 + if (slot && khugepaged_scan.mm_slot != slot) { 483 489 hash_del(&slot->hash); 484 490 list_del(&slot->mm_node); 485 491 free = 1; ··· 486 496 487 497 if (free) { 488 498 mm_flags_clear(MMF_VM_HUGEPAGE, mm); 489 - mm_slot_free(mm_slot_cache, mm_slot); 499 + mm_slot_free(mm_slot_cache, slot); 490 500 mmdrop(mm); 491 - } else if (mm_slot) { 501 + } else if (slot) { 492 502 /* 493 503 * This is required to serialize against 494 504 * hpage_collapse_test_exit() (which is guaranteed to run ··· 1422 1432 return result; 1423 1433 } 1424 1434 1425 - static void collect_mm_slot(struct khugepaged_mm_slot *mm_slot) 1435 + static void collect_mm_slot(struct mm_slot *slot) 1426 1436 { 1427 - struct mm_slot *slot = &mm_slot->slot; 1428 1437 struct mm_struct *mm = slot->mm; 1429 1438 1430 1439 lockdep_assert_held(&khugepaged_mm_lock); ··· 1440 1451 */ 1441 1452 1442 1453 /* khugepaged_mm_lock actually not necessary for the below */ 1443 - mm_slot_free(mm_slot_cache, mm_slot); 1454 + mm_slot_free(mm_slot_cache, slot); 1444 1455 mmdrop(mm); 1445 1456 } 1446 1457 } ··· 2383 2394 __acquires(&khugepaged_mm_lock) 2384 2395 { 2385 2396 struct vma_iterator vmi; 2386 - struct khugepaged_mm_slot *mm_slot; 2387 2397 struct mm_slot *slot; 2388 2398 struct mm_struct *mm; 2389 2399 struct vm_area_struct *vma; ··· 2393 2405 *result = SCAN_FAIL; 2394 2406 2395 2407 if (khugepaged_scan.mm_slot) { 2396 - mm_slot = khugepaged_scan.mm_slot; 2397 - slot = &mm_slot->slot; 2408 + slot = khugepaged_scan.mm_slot; 2398 2409 } else { 2399 2410 slot = list_first_entry(&khugepaged_scan.mm_head, 2400 2411 struct mm_slot, mm_node); 2401 - mm_slot = mm_slot_entry(slot, struct khugepaged_mm_slot, slot); 2402 2412 khugepaged_scan.address = 0; 2403 - khugepaged_scan.mm_slot = mm_slot; 2413 + khugepaged_scan.mm_slot = slot; 2404 2414 } 2405 2415 spin_unlock(&khugepaged_mm_lock); 2406 2416 ··· 2496 2510 breakouterloop_mmap_lock: 2497 2511 2498 2512 spin_lock(&khugepaged_mm_lock); 2499 - VM_BUG_ON(khugepaged_scan.mm_slot != mm_slot); 2513 + VM_BUG_ON(khugepaged_scan.mm_slot != slot); 2500 2514 /* 2501 2515 * Release the current mm_slot if this mm is about to die, or 2502 2516 * if we scanned all vmas of this mm. ··· 2508 2522 * mm_slot not pointing to the exiting mm. 2509 2523 */ 2510 2524 if (!list_is_last(&slot->mm_node, &khugepaged_scan.mm_head)) { 2511 - slot = list_next_entry(slot, mm_node); 2512 - khugepaged_scan.mm_slot = 2513 - mm_slot_entry(slot, struct khugepaged_mm_slot, slot); 2525 + khugepaged_scan.mm_slot = list_next_entry(slot, mm_node); 2514 2526 khugepaged_scan.address = 0; 2515 2527 } else { 2516 2528 khugepaged_scan.mm_slot = NULL; 2517 2529 khugepaged_full_scans++; 2518 2530 } 2519 2531 2520 - collect_mm_slot(mm_slot); 2532 + collect_mm_slot(slot); 2521 2533 } 2522 2534 2523 2535 return progress; ··· 2602 2618 2603 2619 static int khugepaged(void *none) 2604 2620 { 2605 - struct khugepaged_mm_slot *mm_slot; 2621 + struct mm_slot *slot; 2606 2622 2607 2623 set_freezable(); 2608 2624 set_user_nice(current, MAX_NICE); ··· 2613 2629 } 2614 2630 2615 2631 spin_lock(&khugepaged_mm_lock); 2616 - mm_slot = khugepaged_scan.mm_slot; 2632 + slot = khugepaged_scan.mm_slot; 2617 2633 khugepaged_scan.mm_slot = NULL; 2618 - if (mm_slot) 2619 - collect_mm_slot(mm_slot); 2634 + if (slot) 2635 + collect_mm_slot(slot); 2620 2636 spin_unlock(&khugepaged_mm_lock); 2621 2637 return 0; 2622 2638 }