cc'ing dri-devel. > >From e314a1a1583e585d062dfc30c8aad8bf5380510b Mon Sep 17 00:00:00 2001 > From: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx> > Date: Mon, 19 May 2014 18:43:21 +0900 > Subject: [PATCH] gpu/drm/ttm: Use mutex_lock_killable() for shrinker functions. > > I can observe that RHEL7 environment stalls with 100% CPU usage when a > certain type of memory pressure is given. While the shrinker functions > are called by shrink_slab() before the OOM killer is triggered, the stall > lasts for many minutes. > > I added debug printk() and observed that many threads are blocked for more > than 10 seconds at ttm_dma_pool_shrink_count()/ttm_dma_pool_shrink_scan() > functions. Since the kswapd can call these functions later, the current > thread can return from these functions as soon as chosen by the OOM killer. > > This patch changes "mutex_lock();" to "if (mutex_lock_killable()) return ...;" > so that any threads can promptly give up. (By the way, as far as I tested, > changing to "if (!mutex_trylock()) return ...;" likely shortens the duration > of stall. Maybe we don't need to wait for mutex if someone is already calling > these functions.) > > Signed-off-by: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx> > --- > drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c > index 1b79bf0..f75dab8 100644 > --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c > +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c > @@ -1012,7 +1012,8 @@ ttm_dma_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) > if (list_empty(&_manager->pools)) > return SHRINK_STOP; > > - mutex_lock(&_manager->lock); > + if (mutex_lock_killable(&_manager->lock)) > + return SHRINK_STOP; > pool_offset = pool_offset % _manager->npools; > list_for_each_entry(p, &_manager->pools, pools) { > unsigned nr_free; > @@ -1043,7 +1044,8 @@ ttm_dma_pool_shrink_count(struct shrinker *shrink, struct shrink_control *sc) > struct device_pools *p; > unsigned long count = 0; > > - mutex_lock(&_manager->lock); > + if (mutex_lock_killable(&_manager->lock)) > + return 0; > list_for_each_entry(p, &_manager->pools, pools) > count += p->pool->npages_free; > mutex_unlock(&_manager->lock); > _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel