[05/11] drm/tests: helpers: Create an helper to allocate a locking ctx

Message ID 20230710-kms-kunit-actions-rework-v1-5-722c58d72c72@kernel.org
State New
Headers
Series drm: kunit: Switch to kunit actions |

Commit Message

Maxime Ripard July 10, 2023, 7:47 a.m. UTC
  As we get more and more tests, the locking context initialisation
creates more and more boilerplate, both at creation and destruction.

Let's create a helper that will allocate, initialise a context, and
register kunit actions to clean up once the test is done.

Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
 drivers/gpu/drm/tests/drm_kunit_helpers.c | 41 +++++++++++++++++++++++++++++++
 include/drm/drm_kunit_helpers.h           |  2 ++
 2 files changed, 43 insertions(+)
  

Comments

Sui Jingfeng July 17, 2023, 4:50 p.m. UTC | #1
Hi,

On 2023/7/10 15:47, Maxime Ripard wrote:
> As we get more and more tests, the locking context initialisation
> creates more and more boilerplate, both at creation and destruction.
>
> Let's create a helper that will allocate, initialise a context, and
> register kunit actions to clean up once the test is done.
>
> Signed-off-by: Maxime Ripard <mripard@kernel.org>
> ---
>   drivers/gpu/drm/tests/drm_kunit_helpers.c | 41 +++++++++++++++++++++++++++++++
>   include/drm/drm_kunit_helpers.h           |  2 ++
>   2 files changed, 43 insertions(+)
>
> diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> index 38211fea9ae6..40a27c78d692 100644
> --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
> +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> @@ -124,5 +124,46 @@ __drm_kunit_helper_alloc_drm_device_with_driver(struct kunit *test,
>   }
>   EXPORT_SYMBOL_GPL(__drm_kunit_helper_alloc_drm_device_with_driver);
>   
> +static void action_drm_release_context(void *ptr)
> +{
> +	struct drm_modeset_acquire_ctx *ctx = ptr;
> +
> +	drm_modeset_drop_locks(ctx);
> +	drm_modeset_acquire_fini(ctx);
> +}
> +
> +/**
> + * drm_kunit_helper_context_alloc - Allocates an acquire context
> + * @test: The test context object
> + *
> + * Allocates and initializes a modeset acquire context.
> + *
> + * The context is tied to the kunit test context, so we must not call
> + * drm_modeset_acquire_fini() on it, it will be done so automatically.
> + *
> + * Returns:
> + * An ERR_PTR on error, a pointer to the newly allocated context otherwise
> + */
> +struct drm_modeset_acquire_ctx *
> +drm_kunit_helper_acquire_ctx_alloc(struct kunit *test)
> +{
> +	struct drm_modeset_acquire_ctx *ctx;
> +	int ret;
> +
> +	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
> +	KUNIT_ASSERT_NOT_NULL(test, ctx);
> +
> +	drm_modeset_acquire_init(ctx, 0);
> +
> +	ret = kunit_add_action_or_reset(test,
> +					action_drm_release_context,
> +					ctx);
> +	if (ret)
> +		return ERR_PTR(ret);
> +
> +	return ctx;
> +}
> +EXPORT_SYMBOL_GPL(drm_kunit_helper_acquire_ctx_alloc);
> +

I think all of the patch inside this series are quite well.

Personally, I can't find problems in it.


But I still want to ask a question:

Should the managed functions you introduced be prefixed with drmm_ 
(instead of drm_) ?

As mindless programmer may still want to call drm_modeset_acquire_fini() 
on the pointer returned by

drm_kunit_helper_acquire_ctx_alloc()?


>   MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
>   MODULE_LICENSE("GPL");
> diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
> index ed013fdcc1ff..4ba5e10653c6 100644
> --- a/include/drm/drm_kunit_helpers.h
> +++ b/include/drm/drm_kunit_helpers.h
> @@ -87,5 +87,7 @@ __drm_kunit_helper_alloc_drm_device(struct kunit *test,
>   						      sizeof(_type),		\
>   						      offsetof(_type, _member),	\
>   						      _feat))
> +struct drm_modeset_acquire_ctx *
> +drm_kunit_helper_acquire_ctx_alloc(struct kunit *test);
>   
>   #endif // DRM_KUNIT_HELPERS_H_
  
Sui Jingfeng July 17, 2023, 5:08 p.m. UTC | #2
Hi,

On 2023/7/10 15:47, Maxime Ripard wrote:
> As we get more and more tests, the locking context initialisation
> creates more and more boilerplate, both at creation and destruction.
>
> Let's create a helper that will allocate, initialise a context, and
> register kunit actions to clean up once the test is done.
>
> Signed-off-by: Maxime Ripard <mripard@kernel.org>
> ---
>   drivers/gpu/drm/tests/drm_kunit_helpers.c | 41 +++++++++++++++++++++++++++++++
>   include/drm/drm_kunit_helpers.h           |  2 ++
>   2 files changed, 43 insertions(+)
>
> diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> index 38211fea9ae6..40a27c78d692 100644
> --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
> +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> @@ -124,5 +124,46 @@ __drm_kunit_helper_alloc_drm_device_with_driver(struct kunit *test,
>   }
>   EXPORT_SYMBOL_GPL(__drm_kunit_helper_alloc_drm_device_with_driver);
>   
> +static void action_drm_release_context(void *ptr)
> +{
> +	struct drm_modeset_acquire_ctx *ctx = ptr;
> +
> +	drm_modeset_drop_locks(ctx);
> +	drm_modeset_acquire_fini(ctx);
> +}
> +
> +/**
> + * drm_kunit_helper_context_alloc - Allocates an acquire context
> + * @test: The test context object
> + *
> + * Allocates and initializes a modeset acquire context.
> + *
> + * The context is tied to the kunit test context, so we must not call
> + * drm_modeset_acquire_fini() on it, it will be done so automatically.
> + *
> + * Returns:
> + * An ERR_PTR on error, a pointer to the newly allocated context otherwise
> + */
> +struct drm_modeset_acquire_ctx *
> +drm_kunit_helper_acquire_ctx_alloc(struct kunit *test)
> +{
> +	struct drm_modeset_acquire_ctx *ctx;
> +	int ret;
> +
> +	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);

Because kunit_kzalloc() is also managed,

Is there any possibility that kfree(ctx) get called before 
action_drm_release_context(ctx) ?

Currently, I can't find where the order is guaranteed.

> +	KUNIT_ASSERT_NOT_NULL(test, ctx);
> +
> +	drm_modeset_acquire_init(ctx, 0);
> +
> +	ret = kunit_add_action_or_reset(test,
> +					action_drm_release_context,
> +					ctx);
> +	if (ret)
> +		return ERR_PTR(ret);
> +
> +	return ctx;
> +}
> +EXPORT_SYMBOL_GPL(drm_kunit_helper_acquire_ctx_alloc);
> +
>   MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
>   MODULE_LICENSE("GPL");
> diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
> index ed013fdcc1ff..4ba5e10653c6 100644
> --- a/include/drm/drm_kunit_helpers.h
> +++ b/include/drm/drm_kunit_helpers.h
> @@ -87,5 +87,7 @@ __drm_kunit_helper_alloc_drm_device(struct kunit *test,
>   						      sizeof(_type),		\
>   						      offsetof(_type, _member),	\
>   						      _feat))
> +struct drm_modeset_acquire_ctx *
> +drm_kunit_helper_acquire_ctx_alloc(struct kunit *test);
>   
>   #endif // DRM_KUNIT_HELPERS_H_
  
Javier Martinez Canillas July 19, 2023, 7:11 p.m. UTC | #3
Maxime Ripard <mripard@kernel.org> writes:

> As we get more and more tests, the locking context initialisation
> creates more and more boilerplate, both at creation and destruction.
>
> Let's create a helper that will allocate, initialise a context, and
> register kunit actions to clean up once the test is done.
>
> Signed-off-by: Maxime Ripard <mripard@kernel.org>
> ---

Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
  
Javier Martinez Canillas July 19, 2023, 7:12 p.m. UTC | #4
suijingfeng <suijingfeng@loongson.cn> writes:

> Hi,
>
> On 2023/7/10 15:47, Maxime Ripard wrote:

[...]

>> +
>> +/**
>> + * drm_kunit_helper_context_alloc - Allocates an acquire context
>> + * @test: The test context object
>> + *
>> + * Allocates and initializes a modeset acquire context.
>> + *
>> + * The context is tied to the kunit test context, so we must not call
>> + * drm_modeset_acquire_fini() on it, it will be done so automatically.
>> + *
>> + * Returns:
>> + * An ERR_PTR on error, a pointer to the newly allocated context otherwise
>> + */
>> +struct drm_modeset_acquire_ctx *
>> +drm_kunit_helper_acquire_ctx_alloc(struct kunit *test)
>> +{
>> +	struct drm_modeset_acquire_ctx *ctx;
>> +	int ret;
>> +
>> +	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
>> +	KUNIT_ASSERT_NOT_NULL(test, ctx);
>> +
>> +	drm_modeset_acquire_init(ctx, 0);
>> +
>> +	ret = kunit_add_action_or_reset(test,
>> +					action_drm_release_context,
>> +					ctx);
>> +	if (ret)
>> +		return ERR_PTR(ret);
>> +
>> +	return ctx;
>> +}
>> +EXPORT_SYMBOL_GPL(drm_kunit_helper_acquire_ctx_alloc);
>> +
>
> I think all of the patch inside this series are quite well.
>
> Personally, I can't find problems in it.
>
>
> But I still want to ask a question:
>
> Should the managed functions you introduced be prefixed with drmm_ 
> (instead of drm_) ?
>

That's a good question. But personally I think that the drmm_ prefix
should be reserved for drm_device managed resources and helpers.

> As mindless programmer may still want to call drm_modeset_acquire_fini() 
> on the pointer returned by
>
> drm_kunit_helper_acquire_ctx_alloc()?
>

The function kernel-doc already mentions that there's no need to do that
and that will be done automatically by kunit. So shouldn't be different of
other functions helper where the programmer didn't read the documentation.
  
Javier Martinez Canillas July 19, 2023, 7:24 p.m. UTC | #5
suijingfeng <suijingfeng@loongson.cn> writes:

> Hi,
>
> On 2023/7/10 15:47, Maxime Ripard wrote:
>> As we get more and more tests, the locking context initialisation

[...]

>> +/**
>> + * drm_kunit_helper_context_alloc - Allocates an acquire context
>> + * @test: The test context object
>> + *
>> + * Allocates and initializes a modeset acquire context.
>> + *
>> + * The context is tied to the kunit test context, so we must not call
>> + * drm_modeset_acquire_fini() on it, it will be done so automatically.
>> + *
>> + * Returns:
>> + * An ERR_PTR on error, a pointer to the newly allocated context otherwise
>> + */
>> +struct drm_modeset_acquire_ctx *
>> +drm_kunit_helper_acquire_ctx_alloc(struct kunit *test)
>> +{
>> +	struct drm_modeset_acquire_ctx *ctx;
>> +	int ret;
>> +
>> +	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
>
> Because kunit_kzalloc() is also managed,
>
> Is there any possibility that kfree(ctx) get called before 
> action_drm_release_context(ctx) ?
>
> Currently, I can't find where the order is guaranteed.
>

It isn't documented indeed in Documentation/dev-tools/kunit/usage.rst but
the kunit_add_action() kernel-doc says:

"All functions registered with kunit_add_action() will execute in the
opposite order to that they were registered in".

And now that kunit_kzalloc() and friends are also implemented using the
cleanup actions, it will be part of that execution chain.

Probably the kunit docs can make this more clear.
  
Maxime Ripard July 20, 2023, 10:07 a.m. UTC | #6
On Wed, Jul 19, 2023 at 09:12:14PM +0200, Javier Martinez Canillas wrote:
> suijingfeng <suijingfeng@loongson.cn> writes:
> 
> > Hi,
> >
> > On 2023/7/10 15:47, Maxime Ripard wrote:
> 
> [...]
> 
> >> +
> >> +/**
> >> + * drm_kunit_helper_context_alloc - Allocates an acquire context
> >> + * @test: The test context object
> >> + *
> >> + * Allocates and initializes a modeset acquire context.
> >> + *
> >> + * The context is tied to the kunit test context, so we must not call
> >> + * drm_modeset_acquire_fini() on it, it will be done so automatically.
> >> + *
> >> + * Returns:
> >> + * An ERR_PTR on error, a pointer to the newly allocated context otherwise
> >> + */
> >> +struct drm_modeset_acquire_ctx *
> >> +drm_kunit_helper_acquire_ctx_alloc(struct kunit *test)
> >> +{
> >> +	struct drm_modeset_acquire_ctx *ctx;
> >> +	int ret;
> >> +
> >> +	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
> >> +	KUNIT_ASSERT_NOT_NULL(test, ctx);
> >> +
> >> +	drm_modeset_acquire_init(ctx, 0);
> >> +
> >> +	ret = kunit_add_action_or_reset(test,
> >> +					action_drm_release_context,
> >> +					ctx);
> >> +	if (ret)
> >> +		return ERR_PTR(ret);
> >> +
> >> +	return ctx;
> >> +}
> >> +EXPORT_SYMBOL_GPL(drm_kunit_helper_acquire_ctx_alloc);
> >> +
> >
> > I think all of the patch inside this series are quite well.
> >
> > Personally, I can't find problems in it.
> >
> >
> > But I still want to ask a question:
> >
> > Should the managed functions you introduced be prefixed with drmm_ 
> > (instead of drm_) ?
> >
> 
> That's a good question. But personally I think that the drmm_ prefix
> should be reserved for drm_device managed resources and helpers.

Yeah, to me drmm functions are meant for resources that are tied to the
DRM device lifetime. These resources are tied to the test lifetime, so
they shouldn't share the same prefix.

> > As mindless programmer may still want to call drm_modeset_acquire_fini() 
> > on the pointer returned by
> >
> > drm_kunit_helper_acquire_ctx_alloc()?
> >
> 
> The function kernel-doc already mentions that there's no need to do that
> and that will be done automatically by kunit. So shouldn't be different of
> other functions helper where the programmer didn't read the documentation.

Right

Maxime
  
Sui Jingfeng July 20, 2023, 10:21 a.m. UTC | #7
Hi,


On 2023/7/20 18:07, Maxime Ripard wrote:
> On Wed, Jul 19, 2023 at 09:12:14PM +0200, Javier Martinez Canillas wrote:
>> suijingfeng <suijingfeng@loongson.cn> writes:
>>
>>> Hi,
>>>
>>> On 2023/7/10 15:47, Maxime Ripard wrote:
>> [...]
>>
>>>> +
>>>> +/**
>>>> + * drm_kunit_helper_context_alloc - Allocates an acquire context
>>>> + * @test: The test context object
>>>> + *
>>>> + * Allocates and initializes a modeset acquire context.
>>>> + *
>>>> + * The context is tied to the kunit test context, so we must not call
>>>> + * drm_modeset_acquire_fini() on it, it will be done so automatically.
>>>> + *
>>>> + * Returns:
>>>> + * An ERR_PTR on error, a pointer to the newly allocated context otherwise
>>>> + */
>>>> +struct drm_modeset_acquire_ctx *
>>>> +drm_kunit_helper_acquire_ctx_alloc(struct kunit *test)
>>>> +{
>>>> +	struct drm_modeset_acquire_ctx *ctx;
>>>> +	int ret;
>>>> +
>>>> +	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
>>>> +	KUNIT_ASSERT_NOT_NULL(test, ctx);
>>>> +
>>>> +	drm_modeset_acquire_init(ctx, 0);
>>>> +
>>>> +	ret = kunit_add_action_or_reset(test,
>>>> +					action_drm_release_context,
>>>> +					ctx);
>>>> +	if (ret)
>>>> +		return ERR_PTR(ret);
>>>> +
>>>> +	return ctx;
>>>> +}
>>>> +EXPORT_SYMBOL_GPL(drm_kunit_helper_acquire_ctx_alloc);
>>>> +
>>> I think all of the patch inside this series are quite well.
>>>
>>> Personally, I can't find problems in it.
>>>
>>>
>>> But I still want to ask a question:
>>>
>>> Should the managed functions you introduced be prefixed with drmm_
>>> (instead of drm_) ?
>>>
>> That's a good question. But personally I think that the drmm_ prefix
>> should be reserved for drm_device managed resources and helpers.
> Yeah, to me drmm functions are meant for resources that are tied to the
> DRM device lifetime. These resources are tied to the test lifetime, so
> they shouldn't share the same prefix.


Okay then,

Thanks for reply.


>>> As mindless programmer may still want to call drm_modeset_acquire_fini()
>>> on the pointer returned by
>>>
>>> drm_kunit_helper_acquire_ctx_alloc()?
>>>
>> The function kernel-doc already mentions that there's no need to do that
>> and that will be done automatically by kunit. So shouldn't be different of
>> other functions helper where the programmer didn't read the documentation.
> Right
>
> Maxime
  

Patch

diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c
index 38211fea9ae6..40a27c78d692 100644
--- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
+++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
@@ -124,5 +124,46 @@  __drm_kunit_helper_alloc_drm_device_with_driver(struct kunit *test,
 }
 EXPORT_SYMBOL_GPL(__drm_kunit_helper_alloc_drm_device_with_driver);
 
+static void action_drm_release_context(void *ptr)
+{
+	struct drm_modeset_acquire_ctx *ctx = ptr;
+
+	drm_modeset_drop_locks(ctx);
+	drm_modeset_acquire_fini(ctx);
+}
+
+/**
+ * drm_kunit_helper_context_alloc - Allocates an acquire context
+ * @test: The test context object
+ *
+ * Allocates and initializes a modeset acquire context.
+ *
+ * The context is tied to the kunit test context, so we must not call
+ * drm_modeset_acquire_fini() on it, it will be done so automatically.
+ *
+ * Returns:
+ * An ERR_PTR on error, a pointer to the newly allocated context otherwise
+ */
+struct drm_modeset_acquire_ctx *
+drm_kunit_helper_acquire_ctx_alloc(struct kunit *test)
+{
+	struct drm_modeset_acquire_ctx *ctx;
+	int ret;
+
+	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, ctx);
+
+	drm_modeset_acquire_init(ctx, 0);
+
+	ret = kunit_add_action_or_reset(test,
+					action_drm_release_context,
+					ctx);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return ctx;
+}
+EXPORT_SYMBOL_GPL(drm_kunit_helper_acquire_ctx_alloc);
+
 MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
 MODULE_LICENSE("GPL");
diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
index ed013fdcc1ff..4ba5e10653c6 100644
--- a/include/drm/drm_kunit_helpers.h
+++ b/include/drm/drm_kunit_helpers.h
@@ -87,5 +87,7 @@  __drm_kunit_helper_alloc_drm_device(struct kunit *test,
 						      sizeof(_type),		\
 						      offsetof(_type, _member),	\
 						      _feat))
+struct drm_modeset_acquire_ctx *
+drm_kunit_helper_acquire_ctx_alloc(struct kunit *test);
 
 #endif // DRM_KUNIT_HELPERS_H_