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

Configure Feed

Select the types of activity you want to include in your feed.

drm/shmem-helper: Use refcount_t for pages_use_count

Use atomic refcount_t helper for pages_use_count to optimize pin/unpin
functions by skipping reservation locking while GEM's pin refcount > 1.

Acked-by: Maxime Ripard <mripard@kernel.org>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Suggested-by: Boris Brezillon <boris.brezillon@collabora.com>
Acked-by: Thomas Zimmermann <tzimmermann@suse.d>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250322212608.40511-9-dmitry.osipenko@collabora.com

+22 -25
+15 -18
drivers/gpu/drm/drm_gem_shmem_helper.c
··· 176 176 if (shmem->pages) 177 177 drm_gem_shmem_put_pages_locked(shmem); 178 178 179 - drm_WARN_ON(obj->dev, shmem->pages_use_count); 179 + drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count)); 180 180 drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count)); 181 181 182 182 dma_resv_unlock(shmem->base.resv); ··· 194 194 195 195 dma_resv_assert_held(shmem->base.resv); 196 196 197 - if (shmem->pages_use_count++ > 0) 197 + if (refcount_inc_not_zero(&shmem->pages_use_count)) 198 198 return 0; 199 199 200 200 pages = drm_gem_get_pages(obj); 201 201 if (IS_ERR(pages)) { 202 202 drm_dbg_kms(obj->dev, "Failed to get pages (%ld)\n", 203 203 PTR_ERR(pages)); 204 - shmem->pages_use_count = 0; 205 204 return PTR_ERR(pages); 206 205 } 207 206 ··· 215 216 #endif 216 217 217 218 shmem->pages = pages; 219 + 220 + refcount_set(&shmem->pages_use_count, 1); 218 221 219 222 return 0; 220 223 } ··· 233 232 234 233 dma_resv_assert_held(shmem->base.resv); 235 234 236 - if (drm_WARN_ON_ONCE(obj->dev, !shmem->pages_use_count)) 237 - return; 238 - 239 - if (--shmem->pages_use_count > 0) 240 - return; 241 - 235 + if (refcount_dec_and_test(&shmem->pages_use_count)) { 242 236 #ifdef CONFIG_X86 243 - if (shmem->map_wc) 244 - set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT); 237 + if (shmem->map_wc) 238 + set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT); 245 239 #endif 246 240 247 - drm_gem_put_pages(obj, shmem->pages, 248 - shmem->pages_mark_dirty_on_put, 249 - shmem->pages_mark_accessed_on_put); 250 - shmem->pages = NULL; 241 + drm_gem_put_pages(obj, shmem->pages, 242 + shmem->pages_mark_dirty_on_put, 243 + shmem->pages_mark_accessed_on_put); 244 + shmem->pages = NULL; 245 + } 251 246 } 252 247 EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); 253 248 ··· 579 582 * mmap'd, vm_open() just grabs an additional reference for the new 580 583 * mm the vma is getting copied into (ie. on fork()). 581 584 */ 582 - if (!drm_WARN_ON_ONCE(obj->dev, !shmem->pages_use_count)) 583 - shmem->pages_use_count++; 585 + drm_WARN_ON_ONCE(obj->dev, 586 + !refcount_inc_not_zero(&shmem->pages_use_count)); 584 587 585 588 dma_resv_unlock(shmem->base.resv); 586 589 ··· 671 674 return; 672 675 673 676 drm_printf_indent(p, indent, "pages_pin_count=%u\n", refcount_read(&shmem->pages_pin_count)); 674 - drm_printf_indent(p, indent, "pages_use_count=%u\n", shmem->pages_use_count); 677 + drm_printf_indent(p, indent, "pages_use_count=%u\n", refcount_read(&shmem->pages_use_count)); 675 678 drm_printf_indent(p, indent, "vmap_use_count=%u\n", shmem->vmap_use_count); 676 679 drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr); 677 680 }
+1 -1
drivers/gpu/drm/lima/lima_gem.c
··· 47 47 } 48 48 49 49 bo->base.pages = pages; 50 - bo->base.pages_use_count = 1; 50 + refcount_set(&bo->base.pages_use_count, 1); 51 51 52 52 mapping_set_unevictable(mapping); 53 53 }
+1 -1
drivers/gpu/drm/panfrost/panfrost_mmu.c
··· 489 489 goto err_unlock; 490 490 } 491 491 bo->base.pages = pages; 492 - bo->base.pages_use_count = 1; 492 + refcount_set(&bo->base.pages_use_count, 1); 493 493 } else { 494 494 pages = bo->base.pages; 495 495 if (pages[page_offset]) {
+4 -4
drivers/gpu/drm/tests/drm_gem_shmem_test.c
··· 134 134 shmem = drm_gem_shmem_create(drm_dev, TEST_SIZE); 135 135 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, shmem); 136 136 KUNIT_EXPECT_NULL(test, shmem->pages); 137 - KUNIT_EXPECT_EQ(test, shmem->pages_use_count, 0); 137 + KUNIT_EXPECT_EQ(test, refcount_read(&shmem->pages_use_count), 0); 138 138 139 139 ret = kunit_add_action_or_reset(test, drm_gem_shmem_free_wrapper, shmem); 140 140 KUNIT_ASSERT_EQ(test, ret, 0); ··· 142 142 ret = drm_gem_shmem_pin(shmem); 143 143 KUNIT_ASSERT_EQ(test, ret, 0); 144 144 KUNIT_ASSERT_NOT_NULL(test, shmem->pages); 145 - KUNIT_EXPECT_EQ(test, shmem->pages_use_count, 1); 145 + KUNIT_EXPECT_EQ(test, refcount_read(&shmem->pages_use_count), 1); 146 146 147 147 for (i = 0; i < (shmem->base.size >> PAGE_SHIFT); i++) 148 148 KUNIT_ASSERT_NOT_NULL(test, shmem->pages[i]); 149 149 150 150 drm_gem_shmem_unpin(shmem); 151 151 KUNIT_EXPECT_NULL(test, shmem->pages); 152 - KUNIT_EXPECT_EQ(test, shmem->pages_use_count, 0); 152 + KUNIT_EXPECT_EQ(test, refcount_read(&shmem->pages_use_count), 0); 153 153 } 154 154 155 155 /* ··· 251 251 sgt = drm_gem_shmem_get_pages_sgt(shmem); 252 252 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sgt); 253 253 KUNIT_ASSERT_NOT_NULL(test, shmem->pages); 254 - KUNIT_EXPECT_EQ(test, shmem->pages_use_count, 1); 254 + KUNIT_EXPECT_EQ(test, refcount_read(&shmem->pages_use_count), 1); 255 255 KUNIT_EXPECT_PTR_EQ(test, sgt, shmem->sgt); 256 256 257 257 for_each_sgtable_sg(sgt, sg, si) {
+1 -1
include/drm/drm_gem_shmem_helper.h
··· 37 37 * Reference count on the pages table. 38 38 * The pages are put when the count reaches zero. 39 39 */ 40 - unsigned int pages_use_count; 40 + refcount_t pages_use_count; 41 41 42 42 /** 43 43 * @pages_pin_count: