]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/vmwgfx: Use kref in vmw_bo_dirty
authorIan Forbes <ian.forbes@broadcom.com>
Thu, 30 Oct 2025 19:36:40 +0000 (14:36 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 12 Dec 2025 17:37:19 +0000 (18:37 +0100)
[ Upstream commit c1962742ffff7e245f935903a4658eb6f94f6058 ]

Rather than using an ad hoc reference count use kref which is atomic
and has underflow warnings.

Signed-off-by: Ian Forbes <ian.forbes@broadcom.com>
Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
Link: https://patch.msgid.link/20251030193640.153697-1-ian.forbes@broadcom.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c

index 74ff2812d66a1b9d08ae92db9f74bc58007b241e..de2498749e276bbe948bb061ce2c0109bc78603f 100644 (file)
@@ -51,22 +51,22 @@ enum vmw_bo_dirty_method {
 
 /**
  * struct vmw_bo_dirty - Dirty information for buffer objects
+ * @ref_count: Reference count for this structure. Must be first member!
  * @start: First currently dirty bit
  * @end: Last currently dirty bit + 1
  * @method: The currently used dirty method
  * @change_count: Number of consecutive method change triggers
- * @ref_count: Reference count for this structure
  * @bitmap_size: The size of the bitmap in bits. Typically equal to the
  * nuber of pages in the bo.
  * @bitmap: A bitmap where each bit represents a page. A set bit means a
  * dirty page.
  */
 struct vmw_bo_dirty {
+       struct   kref ref_count;
        unsigned long start;
        unsigned long end;
        enum vmw_bo_dirty_method method;
        unsigned int change_count;
-       unsigned int ref_count;
        unsigned long bitmap_size;
        unsigned long bitmap[];
 };
@@ -235,7 +235,7 @@ int vmw_bo_dirty_add(struct vmw_bo *vbo)
        int ret;
 
        if (dirty) {
-               dirty->ref_count++;
+               kref_get(&dirty->ref_count);
                return 0;
        }
 
@@ -249,7 +249,7 @@ int vmw_bo_dirty_add(struct vmw_bo *vbo)
        dirty->bitmap_size = num_pages;
        dirty->start = dirty->bitmap_size;
        dirty->end = 0;
-       dirty->ref_count = 1;
+       kref_init(&dirty->ref_count);
        if (num_pages < PAGE_SIZE / sizeof(pte_t)) {
                dirty->method = VMW_BO_DIRTY_PAGETABLE;
        } else {
@@ -288,10 +288,8 @@ void vmw_bo_dirty_release(struct vmw_bo *vbo)
 {
        struct vmw_bo_dirty *dirty = vbo->dirty;
 
-       if (dirty && --dirty->ref_count == 0) {
-               kvfree(dirty);
+       if (dirty && kref_put(&dirty->ref_count, (void *)kvfree))
                vbo->dirty = NULL;
-       }
 }
 
 /**