On 5/28/19 1:39 PM, Vladimir Davydov wrote: > On Tue, May 28, 2019 at 01:37:50PM -0400, Waiman Long wrote: >> On 5/28/19 1:08 PM, Vladimir Davydov wrote: >>>> static void flush_memcg_workqueue(struct kmem_cache *s) >>>> { >>>> + /* >>>> + * memcg_params.dying is synchronized using slab_mutex AND >>>> + * memcg_kmem_wq_lock spinlock, because it's not always >>>> + * possible to grab slab_mutex. >>>> + */ >>>> mutex_lock(&slab_mutex); >>>> + spin_lock(&memcg_kmem_wq_lock); >>>> s->memcg_params.dying = true; >>>> + spin_unlock(&memcg_kmem_wq_lock); >>> I would completely switch from the mutex to the new spin lock - >>> acquiring them both looks weird. >>> >>>> mutex_unlock(&slab_mutex); >>>> >>>> /* >> There are places where the slab_mutex is held and sleeping functions >> like kvzalloc() are called. I understand that taking both mutex and >> spinlocks look ugly, but converting all the slab_mutex critical sections >> to spinlock critical sections will be a major undertaking by itself. So >> I would suggest leaving that for now. > I didn't mean that. I meant taking spin_lock wherever we need to access > the 'dying' flag, even if slab_mutex is held. So that we don't need to > take mutex_lock in flush_memcg_workqueue, where it's used solely for > 'dying' synchronization. OK, that makes sense. Thanks for the clarification. Cheers, Longman