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

Merge tag 'slab-for-7.0-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab

Pull slab fixes from Vlastimil Babka:

- Fix for slab->stride truncation on 64k page systems due to short
type. It was not due to races and lack of barriers in the end. (Harry
Yoo)

- Fix for severe performance regression due to unnecessary sheaf refill
restrictions exposed by mempool allocation strategy. (Vlastimil
Babka)

- Stable fix for potential silent percpu sheaf flushing failures on
PREEMPT_RT. (Vlastimil Babka)

* tag 'slab-for-7.0-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab:
mm/slab: change stride type from unsigned short to unsigned int
mm/slab: allow sheaf refill if blocking is not allowed
slab: distinguish lock and trylock for sheaf_flush_main()

+52 -27
+5 -5
mm/slab.h
··· 59 59 * to save memory. In case ->stride field is not available, 60 60 * such optimizations are disabled. 61 61 */ 62 - unsigned short stride; 62 + unsigned int stride; 63 63 #endif 64 64 }; 65 65 }; ··· 559 559 } 560 560 561 561 #ifdef CONFIG_64BIT 562 - static inline void slab_set_stride(struct slab *slab, unsigned short stride) 562 + static inline void slab_set_stride(struct slab *slab, unsigned int stride) 563 563 { 564 564 slab->stride = stride; 565 565 } 566 - static inline unsigned short slab_get_stride(struct slab *slab) 566 + static inline unsigned int slab_get_stride(struct slab *slab) 567 567 { 568 568 return slab->stride; 569 569 } 570 570 #else 571 - static inline void slab_set_stride(struct slab *slab, unsigned short stride) 571 + static inline void slab_set_stride(struct slab *slab, unsigned int stride) 572 572 { 573 573 VM_WARN_ON_ONCE(stride != sizeof(struct slabobj_ext)); 574 574 } 575 - static inline unsigned short slab_get_stride(struct slab *slab) 575 + static inline unsigned int slab_get_stride(struct slab *slab) 576 576 { 577 577 return sizeof(struct slabobj_ext); 578 578 }
+47 -22
mm/slub.c
··· 2858 2858 * object pointers are moved to a on-stack array under the lock. To bound the 2859 2859 * stack usage, limit each batch to PCS_BATCH_MAX. 2860 2860 * 2861 - * returns true if at least partially flushed 2861 + * Must be called with s->cpu_sheaves->lock locked, returns with the lock 2862 + * unlocked. 2863 + * 2864 + * Returns how many objects are remaining to be flushed 2862 2865 */ 2863 - static bool sheaf_flush_main(struct kmem_cache *s) 2866 + static unsigned int __sheaf_flush_main_batch(struct kmem_cache *s) 2864 2867 { 2865 2868 struct slub_percpu_sheaves *pcs; 2866 2869 unsigned int batch, remaining; 2867 2870 void *objects[PCS_BATCH_MAX]; 2868 2871 struct slab_sheaf *sheaf; 2869 - bool ret = false; 2870 2872 2871 - next_batch: 2872 - if (!local_trylock(&s->cpu_sheaves->lock)) 2873 - return ret; 2873 + lockdep_assert_held(this_cpu_ptr(&s->cpu_sheaves->lock)); 2874 2874 2875 2875 pcs = this_cpu_ptr(s->cpu_sheaves); 2876 2876 sheaf = pcs->main; ··· 2888 2888 2889 2889 stat_add(s, SHEAF_FLUSH, batch); 2890 2890 2891 - ret = true; 2891 + return remaining; 2892 + } 2892 2893 2893 - if (remaining) 2894 - goto next_batch; 2894 + static void sheaf_flush_main(struct kmem_cache *s) 2895 + { 2896 + unsigned int remaining; 2897 + 2898 + do { 2899 + local_lock(&s->cpu_sheaves->lock); 2900 + 2901 + remaining = __sheaf_flush_main_batch(s); 2902 + 2903 + } while (remaining); 2904 + } 2905 + 2906 + /* 2907 + * Returns true if the main sheaf was at least partially flushed. 2908 + */ 2909 + static bool sheaf_try_flush_main(struct kmem_cache *s) 2910 + { 2911 + unsigned int remaining; 2912 + bool ret = false; 2913 + 2914 + do { 2915 + if (!local_trylock(&s->cpu_sheaves->lock)) 2916 + return ret; 2917 + 2918 + ret = true; 2919 + remaining = __sheaf_flush_main_batch(s); 2920 + 2921 + } while (remaining); 2895 2922 2896 2923 return ret; 2897 2924 } ··· 4567 4540 struct slab_sheaf *empty = NULL; 4568 4541 struct slab_sheaf *full; 4569 4542 struct node_barn *barn; 4570 - bool can_alloc; 4543 + bool allow_spin; 4571 4544 4572 4545 lockdep_assert_held(this_cpu_ptr(&s->cpu_sheaves->lock)); 4573 4546 ··· 4588 4561 return NULL; 4589 4562 } 4590 4563 4591 - full = barn_replace_empty_sheaf(barn, pcs->main, 4592 - gfpflags_allow_spinning(gfp)); 4564 + allow_spin = gfpflags_allow_spinning(gfp); 4565 + 4566 + full = barn_replace_empty_sheaf(barn, pcs->main, allow_spin); 4593 4567 4594 4568 if (full) { 4595 4569 stat(s, BARN_GET); ··· 4600 4572 4601 4573 stat(s, BARN_GET_FAIL); 4602 4574 4603 - can_alloc = gfpflags_allow_blocking(gfp); 4604 - 4605 - if (can_alloc) { 4575 + if (allow_spin) { 4606 4576 if (pcs->spare) { 4607 4577 empty = pcs->spare; 4608 4578 pcs->spare = NULL; ··· 4610 4584 } 4611 4585 4612 4586 local_unlock(&s->cpu_sheaves->lock); 4587 + pcs = NULL; 4613 4588 4614 - if (!can_alloc) 4589 + if (!allow_spin) 4615 4590 return NULL; 4616 4591 4617 4592 if (empty) { ··· 4632 4605 if (!full) 4633 4606 return NULL; 4634 4607 4635 - /* 4636 - * we can reach here only when gfpflags_allow_blocking 4637 - * so this must not be an irq 4638 - */ 4639 - local_lock(&s->cpu_sheaves->lock); 4608 + if (!local_trylock(&s->cpu_sheaves->lock)) 4609 + goto barn_put; 4640 4610 pcs = this_cpu_ptr(s->cpu_sheaves); 4641 4611 4642 4612 /* ··· 4664 4640 return pcs; 4665 4641 } 4666 4642 4643 + barn_put: 4667 4644 barn_put_full_sheaf(barn, full); 4668 4645 stat(s, BARN_PUT); 4669 4646 ··· 5729 5704 if (put_fail) 5730 5705 stat(s, BARN_PUT_FAIL); 5731 5706 5732 - if (!sheaf_flush_main(s)) 5707 + if (!sheaf_try_flush_main(s)) 5733 5708 return NULL; 5734 5709 5735 5710 if (!local_trylock(&s->cpu_sheaves->lock))