diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2014-08-03 06:59:35 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-08-04 20:51:36 -0400 |
commit | 11e504cc705e8ccb06ac93a276e11b5e8fee4d40 (patch) | |
tree | 7e6feb5fd586ac760f67a319ce19d3c9e9e9883c | |
parent | 74cd62ea46f19c41ef20a85792414973ba629cde (diff) |
drm/ttm: Fix possible division by 0 in ttm_dma_pool_shrink_scan().
list_empty(&_manager->pools) being false before taking _manager->lock
does not guarantee that _manager->npools != 0 after taking _manager->lock
because _manager->npools is updated under _manager->lock.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: stable <stable@kernel.org> [3.3+]
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index fb8259f69839..b751ffffdf0b 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | |||
@@ -1015,6 +1015,8 @@ ttm_dma_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) | |||
1015 | return SHRINK_STOP; | 1015 | return SHRINK_STOP; |
1016 | 1016 | ||
1017 | mutex_lock(&_manager->lock); | 1017 | mutex_lock(&_manager->lock); |
1018 | if (!_manager->npools) | ||
1019 | goto out; | ||
1018 | pool_offset = pool_offset % _manager->npools; | 1020 | pool_offset = pool_offset % _manager->npools; |
1019 | list_for_each_entry(p, &_manager->pools, pools) { | 1021 | list_for_each_entry(p, &_manager->pools, pools) { |
1020 | unsigned nr_free; | 1022 | unsigned nr_free; |
@@ -1034,6 +1036,7 @@ ttm_dma_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) | |||
1034 | p->pool->dev_name, p->pool->name, current->pid, | 1036 | p->pool->dev_name, p->pool->name, current->pid, |
1035 | nr_free, shrink_pages); | 1037 | nr_free, shrink_pages); |
1036 | } | 1038 | } |
1039 | out: | ||
1037 | mutex_unlock(&_manager->lock); | 1040 | mutex_unlock(&_manager->lock); |
1038 | return freed; | 1041 | return freed; |
1039 | } | 1042 | } |