Re: [Intel-gfx] [PATCH v15 12/23] drm/shmem-helper: Add and use pages_pin_count

2023-08-28 Thread Dmitry Osipenko
On 8/28/23 14:46, Boris Brezillon wrote:
> On Sun, 27 Aug 2023 20:54:38 +0300
> Dmitry Osipenko  wrote:
> 
>> Add separate pages_pin_count for tracking of whether drm-shmem pages are
>> moveable or not. With the addition of memory shrinker support to drm-shmem,
>> the pages_use_count will no longer determine whether pages are hard-pinned
>> in memory, but whether pages exit and are soft-pinned (and could be swapped
>> out). The pages_pin_count > 1 will hard-pin pages in memory.
>>
>> Suggested-by: Boris Brezillon 
>> Signed-off-by: Dmitry Osipenko 
>> ---
>>  drivers/gpu/drm/drm_gem_shmem_helper.c | 22 +-
>>  include/drm/drm_gem_shmem_helper.h | 10 ++
>>  2 files changed, 27 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
>> b/drivers/gpu/drm/drm_gem_shmem_helper.c
>> index d545d3d227d7..1a7e5c332fd8 100644
>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>> @@ -234,14 +234,22 @@ static int drm_gem_shmem_pin_locked(struct 
>> drm_gem_shmem_object *shmem)
>>  
>>  dma_resv_assert_held(shmem->base.resv);
>>  
>> +if (kref_get_unless_zero(>pages_pin_count))
>> +return 0;
>> +
>>  ret = drm_gem_shmem_get_pages_locked(shmem);
>> +if (!ret)
>> +kref_init(>pages_pin_count);
>>  
>>  return ret;
>>  }
>>  
>> -static void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem)
>> +static void drm_gem_shmem_kref_unpin_pages(struct kref *kref)
>>  {
>> -dma_resv_assert_held(shmem->base.resv);
>> +struct drm_gem_shmem_object *shmem;
>> +
>> +shmem = container_of(kref, struct drm_gem_shmem_object,
>> + pages_pin_count);
>>  
>>  drm_gem_shmem_put_pages_locked(shmem);
>>  }
>> @@ -263,6 +271,9 @@ int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem)
>>  
>>  drm_WARN_ON(obj->dev, obj->import_attach);
>>  
>> +if (kref_get_unless_zero(>pages_pin_count))
>> +return 0;
>> +
>>  ret = dma_resv_lock_interruptible(shmem->base.resv, NULL);
>>  if (ret)
>>  return ret;
>> @@ -286,9 +297,10 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object 
>> *shmem)
>>  
>>  drm_WARN_ON(obj->dev, obj->import_attach);
>>  
>> -dma_resv_lock(shmem->base.resv, NULL);
>> -drm_gem_shmem_unpin_locked(shmem);
>> -dma_resv_unlock(shmem->base.resv);
>> +if (kref_put_dma_resv(>pages_pin_count,
>> +  drm_gem_shmem_kref_unpin_pages,
>> +  obj->resv, NULL))
>> +dma_resv_unlock(obj->resv);
>>  }
>>  EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin);
>>  
>> diff --git a/include/drm/drm_gem_shmem_helper.h 
>> b/include/drm/drm_gem_shmem_helper.h
>> index ec2d8b24e3cf..afb7cd671e2a 100644
>> --- a/include/drm/drm_gem_shmem_helper.h
>> +++ b/include/drm/drm_gem_shmem_helper.h
>> @@ -39,6 +39,16 @@ struct drm_gem_shmem_object {
>>   */
>>  unsigned int pages_use_count;
>>  
>> +/**
>> + * @pages_pin_count:
>> + *
>> + * Reference count on the pinned pages table.
>> + * The pages allowed to be evicted and purged by memory
>> + * shrinker only when the count is zero, otherwise pages
>> + * are hard-pinned in memory.
>> + */
>> +struct kref pages_pin_count;
> 
> I know it's tempting to use kref for the pages use/pin count, but I'm
> wondering if we wouldn't be better using a refcount_t, which provides
> overflow/underflow protection while still letting us control how we
> want to handle the locking for 0 <-> 1 transitions. By doing that, we
> avoid introducing core locking changes that might be more
> controversial/longer to get accepted. Besides, I suspect the resulting
> code (the one using a refcount_t) won't be more verbose/complicated (no
> release functions needed if you don't use kref_put(), which makes
> things closer to what we have right now).

Alright, let's try to use refcount_t since Christian also doesn't like kref

-- 
Best regards,
Dmitry



Re: [Intel-gfx] [PATCH v15 12/23] drm/shmem-helper: Add and use pages_pin_count

2023-08-28 Thread Boris Brezillon
On Sun, 27 Aug 2023 20:54:38 +0300
Dmitry Osipenko  wrote:

> Add separate pages_pin_count for tracking of whether drm-shmem pages are
> moveable or not. With the addition of memory shrinker support to drm-shmem,
> the pages_use_count will no longer determine whether pages are hard-pinned
> in memory, but whether pages exit and are soft-pinned (and could be swapped
> out). The pages_pin_count > 1 will hard-pin pages in memory.
> 
> Suggested-by: Boris Brezillon 
> Signed-off-by: Dmitry Osipenko 
> ---
>  drivers/gpu/drm/drm_gem_shmem_helper.c | 22 +-
>  include/drm/drm_gem_shmem_helper.h | 10 ++
>  2 files changed, 27 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
> b/drivers/gpu/drm/drm_gem_shmem_helper.c
> index d545d3d227d7..1a7e5c332fd8 100644
> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
> @@ -234,14 +234,22 @@ static int drm_gem_shmem_pin_locked(struct 
> drm_gem_shmem_object *shmem)
>  
>   dma_resv_assert_held(shmem->base.resv);
>  
> + if (kref_get_unless_zero(>pages_pin_count))
> + return 0;
> +
>   ret = drm_gem_shmem_get_pages_locked(shmem);
> + if (!ret)
> + kref_init(>pages_pin_count);
>  
>   return ret;
>  }
>  
> -static void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem)
> +static void drm_gem_shmem_kref_unpin_pages(struct kref *kref)
>  {
> - dma_resv_assert_held(shmem->base.resv);
> + struct drm_gem_shmem_object *shmem;
> +
> + shmem = container_of(kref, struct drm_gem_shmem_object,
> +  pages_pin_count);
>  
>   drm_gem_shmem_put_pages_locked(shmem);
>  }
> @@ -263,6 +271,9 @@ int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem)
>  
>   drm_WARN_ON(obj->dev, obj->import_attach);
>  
> + if (kref_get_unless_zero(>pages_pin_count))
> + return 0;
> +
>   ret = dma_resv_lock_interruptible(shmem->base.resv, NULL);
>   if (ret)
>   return ret;
> @@ -286,9 +297,10 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object 
> *shmem)
>  
>   drm_WARN_ON(obj->dev, obj->import_attach);
>  
> - dma_resv_lock(shmem->base.resv, NULL);
> - drm_gem_shmem_unpin_locked(shmem);
> - dma_resv_unlock(shmem->base.resv);
> + if (kref_put_dma_resv(>pages_pin_count,
> +   drm_gem_shmem_kref_unpin_pages,
> +   obj->resv, NULL))
> + dma_resv_unlock(obj->resv);
>  }
>  EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin);
>  
> diff --git a/include/drm/drm_gem_shmem_helper.h 
> b/include/drm/drm_gem_shmem_helper.h
> index ec2d8b24e3cf..afb7cd671e2a 100644
> --- a/include/drm/drm_gem_shmem_helper.h
> +++ b/include/drm/drm_gem_shmem_helper.h
> @@ -39,6 +39,16 @@ struct drm_gem_shmem_object {
>*/
>   unsigned int pages_use_count;
>  
> + /**
> +  * @pages_pin_count:
> +  *
> +  * Reference count on the pinned pages table.
> +  * The pages allowed to be evicted and purged by memory
> +  * shrinker only when the count is zero, otherwise pages
> +  * are hard-pinned in memory.
> +  */
> + struct kref pages_pin_count;

I know it's tempting to use kref for the pages use/pin count, but I'm
wondering if we wouldn't be better using a refcount_t, which provides
overflow/underflow protection while still letting us control how we
want to handle the locking for 0 <-> 1 transitions. By doing that, we
avoid introducing core locking changes that might be more
controversial/longer to get accepted. Besides, I suspect the resulting
code (the one using a refcount_t) won't be more verbose/complicated (no
release functions needed if you don't use kref_put(), which makes
things closer to what we have right now).

> +
>   /**
>* @madv: State for madvise
>*



Re: [Intel-gfx] [PATCH v15 12/23] drm/shmem-helper: Add and use pages_pin_count

2023-08-28 Thread Boris Brezillon
On Sun, 27 Aug 2023 20:54:38 +0300
Dmitry Osipenko  wrote:

> Add separate pages_pin_count for tracking of whether drm-shmem pages are
> moveable or not. With the addition of memory shrinker support to drm-shmem,
> the pages_use_count will no longer determine whether pages are hard-pinned
> in memory, but whether pages exit and are soft-pinned (and could be swapped

^exist

> out). The pages_pin_count > 1 will hard-pin pages in memory.
> 
> Suggested-by: Boris Brezillon 
> Signed-off-by: Dmitry Osipenko 
> ---
>  drivers/gpu/drm/drm_gem_shmem_helper.c | 22 +-
>  include/drm/drm_gem_shmem_helper.h | 10 ++
>  2 files changed, 27 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
> b/drivers/gpu/drm/drm_gem_shmem_helper.c
> index d545d3d227d7..1a7e5c332fd8 100644
> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
> @@ -234,14 +234,22 @@ static int drm_gem_shmem_pin_locked(struct 
> drm_gem_shmem_object *shmem)
>  
>   dma_resv_assert_held(shmem->base.resv);
>  
> + if (kref_get_unless_zero(>pages_pin_count))
> + return 0;
> +
>   ret = drm_gem_shmem_get_pages_locked(shmem);
> + if (!ret)
> + kref_init(>pages_pin_count);
>  
>   return ret;
>  }
>  
> -static void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem)
> +static void drm_gem_shmem_kref_unpin_pages(struct kref *kref)
>  {
> - dma_resv_assert_held(shmem->base.resv);
> + struct drm_gem_shmem_object *shmem;
> +
> + shmem = container_of(kref, struct drm_gem_shmem_object,
> +  pages_pin_count);
>  
>   drm_gem_shmem_put_pages_locked(shmem);
>  }
> @@ -263,6 +271,9 @@ int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem)
>  
>   drm_WARN_ON(obj->dev, obj->import_attach);
>  
> + if (kref_get_unless_zero(>pages_pin_count))
> + return 0;
> +
>   ret = dma_resv_lock_interruptible(shmem->base.resv, NULL);
>   if (ret)
>   return ret;
> @@ -286,9 +297,10 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object 
> *shmem)
>  
>   drm_WARN_ON(obj->dev, obj->import_attach);
>  
> - dma_resv_lock(shmem->base.resv, NULL);
> - drm_gem_shmem_unpin_locked(shmem);
> - dma_resv_unlock(shmem->base.resv);
> + if (kref_put_dma_resv(>pages_pin_count,
> +   drm_gem_shmem_kref_unpin_pages,
> +   obj->resv, NULL))
> + dma_resv_unlock(obj->resv);
>  }
>  EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin);
>  
> diff --git a/include/drm/drm_gem_shmem_helper.h 
> b/include/drm/drm_gem_shmem_helper.h
> index ec2d8b24e3cf..afb7cd671e2a 100644
> --- a/include/drm/drm_gem_shmem_helper.h
> +++ b/include/drm/drm_gem_shmem_helper.h
> @@ -39,6 +39,16 @@ struct drm_gem_shmem_object {
>*/
>   unsigned int pages_use_count;
>  
> + /**
> +  * @pages_pin_count:
> +  *
> +  * Reference count on the pinned pages table.
> +  * The pages allowed to be evicted and purged by memory
> +  * shrinker only when the count is zero, otherwise pages
> +  * are hard-pinned in memory.
> +  */
> + struct kref pages_pin_count;
> +
>   /**
>* @madv: State for madvise
>*



[Intel-gfx] [PATCH v15 12/23] drm/shmem-helper: Add and use pages_pin_count

2023-08-27 Thread Dmitry Osipenko
Add separate pages_pin_count for tracking of whether drm-shmem pages are
moveable or not. With the addition of memory shrinker support to drm-shmem,
the pages_use_count will no longer determine whether pages are hard-pinned
in memory, but whether pages exit and are soft-pinned (and could be swapped
out). The pages_pin_count > 1 will hard-pin pages in memory.

Suggested-by: Boris Brezillon 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 22 +-
 include/drm/drm_gem_shmem_helper.h | 10 ++
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index d545d3d227d7..1a7e5c332fd8 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -234,14 +234,22 @@ static int drm_gem_shmem_pin_locked(struct 
drm_gem_shmem_object *shmem)
 
dma_resv_assert_held(shmem->base.resv);
 
+   if (kref_get_unless_zero(>pages_pin_count))
+   return 0;
+
ret = drm_gem_shmem_get_pages_locked(shmem);
+   if (!ret)
+   kref_init(>pages_pin_count);
 
return ret;
 }
 
-static void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem)
+static void drm_gem_shmem_kref_unpin_pages(struct kref *kref)
 {
-   dma_resv_assert_held(shmem->base.resv);
+   struct drm_gem_shmem_object *shmem;
+
+   shmem = container_of(kref, struct drm_gem_shmem_object,
+pages_pin_count);
 
drm_gem_shmem_put_pages_locked(shmem);
 }
@@ -263,6 +271,9 @@ int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem)
 
drm_WARN_ON(obj->dev, obj->import_attach);
 
+   if (kref_get_unless_zero(>pages_pin_count))
+   return 0;
+
ret = dma_resv_lock_interruptible(shmem->base.resv, NULL);
if (ret)
return ret;
@@ -286,9 +297,10 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object 
*shmem)
 
drm_WARN_ON(obj->dev, obj->import_attach);
 
-   dma_resv_lock(shmem->base.resv, NULL);
-   drm_gem_shmem_unpin_locked(shmem);
-   dma_resv_unlock(shmem->base.resv);
+   if (kref_put_dma_resv(>pages_pin_count,
+ drm_gem_shmem_kref_unpin_pages,
+ obj->resv, NULL))
+   dma_resv_unlock(obj->resv);
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin);
 
diff --git a/include/drm/drm_gem_shmem_helper.h 
b/include/drm/drm_gem_shmem_helper.h
index ec2d8b24e3cf..afb7cd671e2a 100644
--- a/include/drm/drm_gem_shmem_helper.h
+++ b/include/drm/drm_gem_shmem_helper.h
@@ -39,6 +39,16 @@ struct drm_gem_shmem_object {
 */
unsigned int pages_use_count;
 
+   /**
+* @pages_pin_count:
+*
+* Reference count on the pinned pages table.
+* The pages allowed to be evicted and purged by memory
+* shrinker only when the count is zero, otherwise pages
+* are hard-pinned in memory.
+*/
+   struct kref pages_pin_count;
+
/**
 * @madv: State for madvise
 *
-- 
2.41.0