]> git.ipfire.org Git - thirdparty/kernel/linux.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)
committerZack Rusin <zack.rusin@broadcom.com>
Fri, 7 Nov 2025 05:00:53 +0000 (00:00 -0500)
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
drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c

index 7de20e56082c8746d29e624b0ffbb9167d4983e8..fd4e76486f2d1b3901c9393a0eb15c2fe2c113cd 100644 (file)
@@ -32,22 +32,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[];
 };
@@ -221,7 +221,7 @@ int vmw_bo_dirty_add(struct vmw_bo *vbo)
        int ret;
 
        if (dirty) {
-               dirty->ref_count++;
+               kref_get(&dirty->ref_count);
                return 0;
        }
 
@@ -235,7 +235,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 {
@@ -274,10 +274,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;
-       }
 }
 
 /**