From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: Dave Airlie <airlied@linux.ie>
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>,
linux-kernel@vger.kernel.org,
DRI mailing list <dri-devel@lists.freedesktop.org>,
glommer@openvz.org, mgorman@suse.de, dchinner@redhat.com
Subject: Re: [PATCH] gpu/drm/ttm: Pass GFP flags in order to avoid deadlock.
Date: Tue, 20 May 2014 09:48:50 -0400 [thread overview]
Message-ID: <20140520134849.GC3045@localhost.localdomain> (raw)
In-Reply-To: <alpine.DEB.2.00.1405200140230.20503@skynet.skynet.ie>
On Tue, May 20, 2014 at 01:40:40AM +0100, Dave Airlie wrote:
>
> cc'ing dri-devel.
It looks pretty simple and correct . I can test it tomorrow and make sure it works
right.
>
> > >From d0d57745ba23faf605b0f249b57d283fe1a8ee60 Mon Sep 17 00:00:00 2001
> > From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> > Date: Mon, 19 May 2014 17:59:03 +0900
> > Subject: [PATCH] gpu/drm/ttm: Pass GFP flags in order to avoid deadlock.
> >
> > Commit 7dc19d5a "drivers: convert shrinkers to new count/scan API" added
> > deadlock warnings that ttm_page_pool_free() and ttm_dma_page_pool_free()
> > are currently doing GFP_KERNEL allocation.
> >
> > But these functions did not get updated to receive gfp_t argument.
> > This patch explicitly passes sc->gfp_mask or GFP_KERNEL to these functions,
> > and removes the deadlock warning.
> >
> > Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> > ---
> > drivers/gpu/drm/ttm/ttm_page_alloc.c | 19 ++++++++++---------
> > drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 19 +++++++++----------
> > 2 files changed, 19 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
> > index 863bef9..ba8f78e 100644
> > --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
> > +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
> > @@ -297,8 +297,10 @@ static void ttm_pool_update_free_locked(struct ttm_page_pool *pool,
> > *
> > * @pool: to free the pages from
> > * @free_all: If set to true will free all pages in pool
> > + * @gfp: GFP flags.
> > **/
> > -static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free)
> > +static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free,
> > + gfp_t gfp)
> > {
> > unsigned long irq_flags;
> > struct page *p;
> > @@ -309,8 +311,7 @@ static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free)
> > if (NUM_PAGES_TO_ALLOC < nr_free)
> > npages_to_free = NUM_PAGES_TO_ALLOC;
> >
> > - pages_to_free = kmalloc(npages_to_free * sizeof(struct page *),
> > - GFP_KERNEL);
> > + pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), gfp);
> > if (!pages_to_free) {
> > pr_err("Failed to allocate memory for pool free operation\n");
> > return 0;
> > @@ -382,9 +383,7 @@ out:
> > *
> > * XXX: (dchinner) Deadlock warning!
> > *
> > - * ttm_page_pool_free() does memory allocation using GFP_KERNEL. that means
> > - * this can deadlock when called a sc->gfp_mask that is not equal to
> > - * GFP_KERNEL.
> > + * We need to pass sc->gfp_mask to ttm_page_pool_free().
> > *
> > * This code is crying out for a shrinker per pool....
> > */
> > @@ -405,7 +404,8 @@ ttm_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
> > if (shrink_pages == 0)
> > break;
> > pool = &_manager->pools[(i + pool_offset)%NUM_POOLS];
> > - shrink_pages = ttm_page_pool_free(pool, nr_free);
> > + shrink_pages = ttm_page_pool_free(pool, nr_free,
> > + sc->gfp_mask);
> > freed += nr_free - shrink_pages;
> > }
> > return freed;
> > @@ -706,7 +706,7 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags,
> > }
> > spin_unlock_irqrestore(&pool->lock, irq_flags);
> > if (npages)
> > - ttm_page_pool_free(pool, npages);
> > + ttm_page_pool_free(pool, npages, GFP_KERNEL);
> > }
> >
> > /*
> > @@ -846,7 +846,8 @@ void ttm_page_alloc_fini(void)
> > ttm_pool_mm_shrink_fini(_manager);
> >
> > for (i = 0; i < NUM_POOLS; ++i)
> > - ttm_page_pool_free(&_manager->pools[i], FREE_ALL_PAGES);
> > + ttm_page_pool_free(&_manager->pools[i], FREE_ALL_PAGES,
> > + GFP_KERNEL);
> >
> > kobject_put(&_manager->kobj);
> > _manager = NULL;
> > diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
> > index fb8259f..1b79bf0 100644
> > --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
> > +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
> > @@ -411,8 +411,10 @@ static void ttm_dma_page_put(struct dma_pool *pool, struct dma_page *d_page)
> > *
> > * @pool: to free the pages from
> > * @nr_free: If set to true will free all pages in pool
> > + * @gfp: GFP flags.
> > **/
> > -static unsigned ttm_dma_page_pool_free(struct dma_pool *pool, unsigned nr_free)
> > +static unsigned ttm_dma_page_pool_free(struct dma_pool *pool, unsigned nr_free,
> > + gfp_t gfp)
> > {
> > unsigned long irq_flags;
> > struct dma_page *dma_p, *tmp;
> > @@ -430,8 +432,7 @@ static unsigned ttm_dma_page_pool_free(struct dma_pool *pool, unsigned nr_free)
> > npages_to_free, nr_free);
> > }
> > #endif
> > - pages_to_free = kmalloc(npages_to_free * sizeof(struct page *),
> > - GFP_KERNEL);
> > + pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), gfp);
> >
> > if (!pages_to_free) {
> > pr_err("%s: Failed to allocate memory for pool free operation\n",
> > @@ -530,7 +531,7 @@ static void ttm_dma_free_pool(struct device *dev, enum pool_type type)
> > if (pool->type != type)
> > continue;
> > /* Takes a spinlock.. */
> > - ttm_dma_page_pool_free(pool, FREE_ALL_PAGES);
> > + ttm_dma_page_pool_free(pool, FREE_ALL_PAGES, GFP_KERNEL);
> > WARN_ON(((pool->npages_in_use + pool->npages_free) != 0));
> > /* This code path is called after _all_ references to the
> > * struct device has been dropped - so nobody should be
> > @@ -983,7 +984,7 @@ void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev)
> >
> > /* shrink pool if necessary (only on !is_cached pools)*/
> > if (npages)
> > - ttm_dma_page_pool_free(pool, npages);
> > + ttm_dma_page_pool_free(pool, npages, GFP_KERNEL);
> > ttm->state = tt_unpopulated;
> > }
> > EXPORT_SYMBOL_GPL(ttm_dma_unpopulate);
> > @@ -993,10 +994,7 @@ EXPORT_SYMBOL_GPL(ttm_dma_unpopulate);
> > *
> > * XXX: (dchinner) Deadlock warning!
> > *
> > - * ttm_dma_page_pool_free() does GFP_KERNEL memory allocation, and so attention
> > - * needs to be paid to sc->gfp_mask to determine if this can be done or not.
> > - * GFP_KERNEL memory allocation in a GFP_ATOMIC reclaim context woul dbe really
> > - * bad.
> > + * We need to pass sc->gfp_mask to ttm_dma_page_pool_free().
> > *
> > * I'm getting sadder as I hear more pathetical whimpers about needing per-pool
> > * shrinkers
> > @@ -1027,7 +1025,8 @@ ttm_dma_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
> > if (++idx < pool_offset)
> > continue;
> > nr_free = shrink_pages;
> > - shrink_pages = ttm_dma_page_pool_free(p->pool, nr_free);
> > + shrink_pages = ttm_dma_page_pool_free(p->pool, nr_free,
> > + sc->gfp_mask);
> > freed += nr_free - shrink_pages;
> >
> > pr_debug("%s: (%s:%d) Asked to shrink %d, have %d more to go\n",
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
WARNING: multiple messages have this Message-ID (diff)
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: Dave Airlie <airlied@linux.ie>
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>,
dchinner@redhat.com, glommer@openvz.org, mgorman@suse.de,
linux-kernel@vger.kernel.org,
DRI mailing list <dri-devel@lists.freedesktop.org>
Subject: Re: [PATCH] gpu/drm/ttm: Pass GFP flags in order to avoid deadlock.
Date: Tue, 20 May 2014 09:48:50 -0400 [thread overview]
Message-ID: <20140520134849.GC3045@localhost.localdomain> (raw)
In-Reply-To: <alpine.DEB.2.00.1405200140230.20503@skynet.skynet.ie>
On Tue, May 20, 2014 at 01:40:40AM +0100, Dave Airlie wrote:
>
> cc'ing dri-devel.
It looks pretty simple and correct . I can test it tomorrow and make sure it works
right.
>
> > >From d0d57745ba23faf605b0f249b57d283fe1a8ee60 Mon Sep 17 00:00:00 2001
> > From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> > Date: Mon, 19 May 2014 17:59:03 +0900
> > Subject: [PATCH] gpu/drm/ttm: Pass GFP flags in order to avoid deadlock.
> >
> > Commit 7dc19d5a "drivers: convert shrinkers to new count/scan API" added
> > deadlock warnings that ttm_page_pool_free() and ttm_dma_page_pool_free()
> > are currently doing GFP_KERNEL allocation.
> >
> > But these functions did not get updated to receive gfp_t argument.
> > This patch explicitly passes sc->gfp_mask or GFP_KERNEL to these functions,
> > and removes the deadlock warning.
> >
> > Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> > ---
> > drivers/gpu/drm/ttm/ttm_page_alloc.c | 19 ++++++++++---------
> > drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 19 +++++++++----------
> > 2 files changed, 19 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
> > index 863bef9..ba8f78e 100644
> > --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
> > +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
> > @@ -297,8 +297,10 @@ static void ttm_pool_update_free_locked(struct ttm_page_pool *pool,
> > *
> > * @pool: to free the pages from
> > * @free_all: If set to true will free all pages in pool
> > + * @gfp: GFP flags.
> > **/
> > -static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free)
> > +static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free,
> > + gfp_t gfp)
> > {
> > unsigned long irq_flags;
> > struct page *p;
> > @@ -309,8 +311,7 @@ static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free)
> > if (NUM_PAGES_TO_ALLOC < nr_free)
> > npages_to_free = NUM_PAGES_TO_ALLOC;
> >
> > - pages_to_free = kmalloc(npages_to_free * sizeof(struct page *),
> > - GFP_KERNEL);
> > + pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), gfp);
> > if (!pages_to_free) {
> > pr_err("Failed to allocate memory for pool free operation\n");
> > return 0;
> > @@ -382,9 +383,7 @@ out:
> > *
> > * XXX: (dchinner) Deadlock warning!
> > *
> > - * ttm_page_pool_free() does memory allocation using GFP_KERNEL. that means
> > - * this can deadlock when called a sc->gfp_mask that is not equal to
> > - * GFP_KERNEL.
> > + * We need to pass sc->gfp_mask to ttm_page_pool_free().
> > *
> > * This code is crying out for a shrinker per pool....
> > */
> > @@ -405,7 +404,8 @@ ttm_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
> > if (shrink_pages == 0)
> > break;
> > pool = &_manager->pools[(i + pool_offset)%NUM_POOLS];
> > - shrink_pages = ttm_page_pool_free(pool, nr_free);
> > + shrink_pages = ttm_page_pool_free(pool, nr_free,
> > + sc->gfp_mask);
> > freed += nr_free - shrink_pages;
> > }
> > return freed;
> > @@ -706,7 +706,7 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags,
> > }
> > spin_unlock_irqrestore(&pool->lock, irq_flags);
> > if (npages)
> > - ttm_page_pool_free(pool, npages);
> > + ttm_page_pool_free(pool, npages, GFP_KERNEL);
> > }
> >
> > /*
> > @@ -846,7 +846,8 @@ void ttm_page_alloc_fini(void)
> > ttm_pool_mm_shrink_fini(_manager);
> >
> > for (i = 0; i < NUM_POOLS; ++i)
> > - ttm_page_pool_free(&_manager->pools[i], FREE_ALL_PAGES);
> > + ttm_page_pool_free(&_manager->pools[i], FREE_ALL_PAGES,
> > + GFP_KERNEL);
> >
> > kobject_put(&_manager->kobj);
> > _manager = NULL;
> > diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
> > index fb8259f..1b79bf0 100644
> > --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
> > +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
> > @@ -411,8 +411,10 @@ static void ttm_dma_page_put(struct dma_pool *pool, struct dma_page *d_page)
> > *
> > * @pool: to free the pages from
> > * @nr_free: If set to true will free all pages in pool
> > + * @gfp: GFP flags.
> > **/
> > -static unsigned ttm_dma_page_pool_free(struct dma_pool *pool, unsigned nr_free)
> > +static unsigned ttm_dma_page_pool_free(struct dma_pool *pool, unsigned nr_free,
> > + gfp_t gfp)
> > {
> > unsigned long irq_flags;
> > struct dma_page *dma_p, *tmp;
> > @@ -430,8 +432,7 @@ static unsigned ttm_dma_page_pool_free(struct dma_pool *pool, unsigned nr_free)
> > npages_to_free, nr_free);
> > }
> > #endif
> > - pages_to_free = kmalloc(npages_to_free * sizeof(struct page *),
> > - GFP_KERNEL);
> > + pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), gfp);
> >
> > if (!pages_to_free) {
> > pr_err("%s: Failed to allocate memory for pool free operation\n",
> > @@ -530,7 +531,7 @@ static void ttm_dma_free_pool(struct device *dev, enum pool_type type)
> > if (pool->type != type)
> > continue;
> > /* Takes a spinlock.. */
> > - ttm_dma_page_pool_free(pool, FREE_ALL_PAGES);
> > + ttm_dma_page_pool_free(pool, FREE_ALL_PAGES, GFP_KERNEL);
> > WARN_ON(((pool->npages_in_use + pool->npages_free) != 0));
> > /* This code path is called after _all_ references to the
> > * struct device has been dropped - so nobody should be
> > @@ -983,7 +984,7 @@ void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev)
> >
> > /* shrink pool if necessary (only on !is_cached pools)*/
> > if (npages)
> > - ttm_dma_page_pool_free(pool, npages);
> > + ttm_dma_page_pool_free(pool, npages, GFP_KERNEL);
> > ttm->state = tt_unpopulated;
> > }
> > EXPORT_SYMBOL_GPL(ttm_dma_unpopulate);
> > @@ -993,10 +994,7 @@ EXPORT_SYMBOL_GPL(ttm_dma_unpopulate);
> > *
> > * XXX: (dchinner) Deadlock warning!
> > *
> > - * ttm_dma_page_pool_free() does GFP_KERNEL memory allocation, and so attention
> > - * needs to be paid to sc->gfp_mask to determine if this can be done or not.
> > - * GFP_KERNEL memory allocation in a GFP_ATOMIC reclaim context woul dbe really
> > - * bad.
> > + * We need to pass sc->gfp_mask to ttm_dma_page_pool_free().
> > *
> > * I'm getting sadder as I hear more pathetical whimpers about needing per-pool
> > * shrinkers
> > @@ -1027,7 +1025,8 @@ ttm_dma_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
> > if (++idx < pool_offset)
> > continue;
> > nr_free = shrink_pages;
> > - shrink_pages = ttm_dma_page_pool_free(p->pool, nr_free);
> > + shrink_pages = ttm_dma_page_pool_free(p->pool, nr_free,
> > + sc->gfp_mask);
> > freed += nr_free - shrink_pages;
> >
> > pr_debug("%s: (%s:%d) Asked to shrink %d, have %d more to go\n",
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
next prev parent reply other threads:[~2014-05-20 13:49 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-19 14:37 [PATCH] gpu/drm/ttm: Pass GFP flags in order to avoid deadlock Tetsuo Handa
2014-05-20 0:40 ` Dave Airlie
2014-05-20 13:48 ` Konrad Rzeszutek Wilk [this message]
2014-05-20 13:48 ` Konrad Rzeszutek Wilk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140520134849.GC3045@localhost.localdomain \
--to=konrad.wilk@oracle.com \
--cc=airlied@linux.ie \
--cc=dchinner@redhat.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=glommer@openvz.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mgorman@suse.de \
--cc=penguin-kernel@I-love.SAKURA.ne.jp \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.