Linux Kernel Selftest development
 help / color / mirror / Atom feed
From: Benjamin Berg <benjamin@sipsolutions.net>
To: Maxime Ripard <maxime@cerno.tech>, David Gow <davidgow@google.com>
Cc: Matti Vaittinen <mazziesaccount@gmail.com>,
	Brendan Higgins <brendan.higgins@linux.dev>,
	Stephen Boyd <sboyd@kernel.org>,
	Shuah Khan <skhan@linuxfoundation.org>,
	Daniel Latypov <dlatypov@google.com>, Rae Moar <rmoar@google.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	"Rafael J . Wysocki" <rafael@kernel.org>,
	Heikki Krogerus <heikki.krogerus@linux.intel.com>,
	Jonathan Cameron <jic23@kernel.org>,
	linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org,
	kunit-dev@googlegroups.com
Subject: Re: [RFC PATCH v2 1/3] kunit: Add kunit_add_action() to defer a call until test exit
Date: Tue, 04 Apr 2023 19:55:30 +0200	[thread overview]
Message-ID: <4d9b16aa28d4eb6c9d5a158e112abfedbfa2cd4b.camel@sipsolutions.net> (raw)
In-Reply-To: <20230404133231.ingzo7xy7lejpqqb@houat>

Hi,

On Tue, 2023-04-04 at 15:32 +0200, Maxime Ripard wrote:
> [SNIP]
> > +/**
> > + * kunit_add_action() - Defer an 'action' (function call) until the test ends.
> > + * @test: Test case to associate the action with.
> > + * @func: The function to run on test exit
> > + * @ctx: Data passed into @func
> > + * @internal_gfp: gfp to use for internal allocations, if unsure, use GFP_KERNEL
> > + *
> > + * Defer the execution of a function until the test exits, either normally or
> > + * due to a failure.  @ctx is passed as additional context. All functions
> > + * registered with kunit_add_action() will execute in the opposite order to that
> > + * they were registered in.
> > + *
> > + * This is useful for cleaning up allocated memory and resources.
> > + *
> > + * Returns:
> > + *   An opaque "cancellation token", or NULL on error. Pass this token to
> > + *   kunit_remove_action_token() in order to cancel the deferred execution of
> > + *   func().
> > + */
> > +struct kunit_action_ctx *kunit_add_action(struct kunit *test, kunit_defer_function_t func,
> > +                     void *ctx, gfp_t internal_gfp);
> 
> Do we expect any other context than GFP_KERNEL?
> 
> If so, then maybe we can have kunit_add_action() assume GFP_KERNEL and
> add a variant for the odd case where we would actually need a different
> GFP flag.

Does anything other than GFP_KERNEL make sense? I would assume these
functions should only ever be called from a kunit context, i.e. the
passed test is guaranteed to be identical to the value returned by
kunit_get_current_test().

That said, I am happy with merging this in this form. I feel the right
thing here is a patch (with corresponding spatch) that changes all of
the related APIs to remove the gfp argument.

> > +/**
> > + * kunit_remove_action_token() - Cancel a deferred action.
> > + * @test: Test case the action is associated with.
> > + * @cancel_token: The cancellation token returned by kunit_add_action()
> > + *
> > + * Prevent an action deferred using kunit_add_action() from executing when the
> > + * test ends.
> > + *
> > + * You can also use the (test, function, context) triplet to remove an action
> > + * with kunit_remove_action().
> > + */
> > +void kunit_remove_action_token(struct kunit *test, struct kunit_action_ctx *cancel_token);
> 
> It's not clear to me why we still need the token. If
> kunit_remove_action() works fine, why would we need to store the token?
> 
> Can't we just make kunit_add_action() return an int to indicate whether
> it failed or not, and that's it?
> 
> > [SNIP]
> 
> One thing worth pointing is that if kunit_add_action() fails, the
> cleanup function passed as an argument won't run.
> 
> So, if the kzalloc call ever fails, patch 2 will leak its res->data()
> resource for example.
> 
> devm (and drmm) handles this using a variant called
> devm_add_action_or_reset, we should either provide the same variant or
> just go for that behavior by default.

Both version of the function would need a return value. An alternative
might be to make assertions part of the API. But as with dropping the
gfp argument, that seems like a more intrusive change that needs to
happen independently.

Anyway, I am fine with action_or_reset as the default and possibly the
only behaviour. I expect that every API user will want an assertion
that checks for failure here anyway.

Benjamin


If kunit_* functions can assert in error conditions, then the example

void test_func(struct kunit *test)
{
  char u8 *buf = kunit_kzalloc(test, 1024, GFP_KERNEL);
  struct sk_buff *skb_a;
  struct sk_buff *skb_b;
  /* Further variables */

  KUNIT_ASSERT_NOT_NULL(test, buf);

  skb_a = skb_alloc(1024, GFP_KERNEL);
  KUNIT_ASSERT_NOT_NULL(test, skb_a);
  if (kunit_add_cleanup(test, (kunit_defer_function_t) kfree_skb, skb_a))
    KUNIT_ASSERT_FAILURE("Failed to add cleanup");

  /* Or, maybe: */
  skb_b = skb_alloc(1024, GFP_KERNEL);
  KUNIT_ASSERT_NOT_NULL(test, skb_b);
  KUNIT_ASSERT_EQ(test, 0,
                  kunit_add_cleanup(test,
                                    (kunit_defer_function_t) kfree_skb,
                                    skb_b));

  /* run code that may assert */
}


could be shortened to (with a trivial kunit_skb_alloc helper)

void test_func(struct kunit *test)
{
  char u8 *buf = kunit_kzalloc(test, 1024, GFP_KERNEL);
  struct sk_buff *skb_a = kunit_skb_alloc(1024, GFP_KERNEL);
  struct sk_buff *skb_b = kunit_skb_alloc(1024, GFP_KERNEL);
  /* Further variables */

  /* run code that may assert */
}

I should just post a patch for the existing API and see what people say
then ...

  reply	other threads:[~2023-04-04 17:56 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-31  8:04 [RFC PATCH v2 0/3] kunit: Deferred action helpers David Gow
2023-03-31  8:04 ` [RFC PATCH v2 1/3] kunit: Add kunit_add_action() to defer a call until test exit David Gow
2023-04-04 13:32   ` Maxime Ripard
2023-04-04 17:55     ` Benjamin Berg [this message]
2023-04-05  8:09       ` David Gow
2023-04-05  7:47     ` David Gow
2023-04-14  9:53       ` Maxime Ripard
2023-04-14 10:01   ` maxime
2023-04-14 11:00     ` Benjamin Berg
2023-04-14 11:33       ` Maxime Ripard
2023-04-15  8:48       ` David Gow
2023-04-15  8:42     ` David Gow
2023-04-17 11:07       ` Maxime Ripard
2023-03-31  8:04 ` [RFC PATCH v2 2/3] kunit: executor_test: Use kunit_add_action() David Gow
2023-03-31  8:04 ` [RFC PATCH v2 3/3] kunit: kmalloc_array: " David Gow
2023-04-04 17:58   ` Benjamin Berg
2023-04-05  7:48     ` David Gow

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4d9b16aa28d4eb6c9d5a158e112abfedbfa2cd4b.camel@sipsolutions.net \
    --to=benjamin@sipsolutions.net \
    --cc=brendan.higgins@linux.dev \
    --cc=davidgow@google.com \
    --cc=dlatypov@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=jic23@kernel.org \
    --cc=kunit-dev@googlegroups.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=maxime@cerno.tech \
    --cc=mazziesaccount@gmail.com \
    --cc=rafael@kernel.org \
    --cc=rmoar@google.com \
    --cc=sboyd@kernel.org \
    --cc=skhan@linuxfoundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox