From: Catalin Marinas <catalin.marinas@arm.com>
To: Dmitry Safonov <0x7f454c46@gmail.com>
Cc: paulmck@kernel.org, Jakub Kicinski <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>,
"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
rcu@vger.kernel.org
Subject: Re: [TEST] TCP MD5 vs kmemleak
Date: Mon, 8 Jul 2024 12:05:17 +0100 [thread overview]
Message-ID: <ZovH7cWlw9SGcWoJ@arm.com> (raw)
In-Reply-To: <CAJwJo6Y0hfB5royz0D8QPkgpRMxz9G5s81ktZbtHPBdt8EYdEQ@mail.gmail.com>
On Tue, Jul 02, 2024 at 03:08:42AM +0100, Dmitry Safonov wrote:
> On Thu, 20 Jun 2024 at 18:02, Paul E. McKenney <paulmck@kernel.org> wrote:
> > So we need call_rcu() to mark memory flowing through it? If so, we
> > need help from callers of call_rcu() in the case where more than one
> > object is being freed.
>
> Not sure, I think one way to avoid explicitly marking pointers for
> call_rcu() or even avoiding the patch above would be a hackery like
> this:
>
> diff --git a/mm/kmemleak.c b/mm/kmemleak.c
> index d5b6fba44fc9..7a5eb55a155c 100644
> --- a/mm/kmemleak.c
> +++ b/mm/kmemleak.c
> @@ -1587,6 +1587,7 @@ static void kmemleak_cond_resched(struct
> kmemleak_object *object)
> static void kmemleak_scan(void)
> {
> struct kmemleak_object *object;
> + unsigned long gp_start_state;
> struct zone *zone;
> int __maybe_unused i;
> int new_leaks = 0;
> @@ -1630,6 +1631,7 @@ static void kmemleak_scan(void)
> kmemleak_cond_resched(object);
> }
> rcu_read_unlock();
> + gp_start_state = get_state_synchronize_rcu();
>
> #ifdef CONFIG_SMP
> /* per-cpu sections scanning */
> @@ -1690,6 +1692,13 @@ static void kmemleak_scan(void)
> */
> scan_gray_list();
>
> + /*
> + * Wait for the greylist objects potentially migrating from
> + * RCU callbacks or maybe getting freed.
> + */
> + cond_synchronize_rcu(gp_start_state);
> + rcu_barrier();
> +
> /*
> * Check for new or unreferenced objects modified since the previous
> * scan and color them gray until the next scan.
>
>
> -->8--
>
> Not quite sure if this makes sense, my first time at kmemleak code,
> adding Catalin.
> But then if I didn't mess up, it's going to work only for one RCU
> period, so in case some object calls rcu/kfree_rcu() from the
> callback, it's going to be yet a false-positive.
Yeah, I don't think this fully solves the problem.
> Some other options/ideas:
> - more RCU-invasive option which would be adding a mapping function to
> segmented lists of callbacks, which would allow kmemleak to request
> from RCU if the pointer is yet referenced by RCU.
This looks too invasive to me plus additional scanning cost.
> - the third option is for kmemleak to trust RCU and generalize the
> commit above, adding kmemleak_object::flags of OBJECT_RCU, which will
> be set by call_rcu()/kfree_rcu() and unset once the callback is
> invoked for RCU_DONE_TAIL.
This could work, the downside being a kmemleak object lookup every time
call_rcu() is invoked. Well, we do this now for kfree_rcu() already,
though we just mark the object as ignored once.
> - add kmemleak_object::update_jiffies or just directly touch
> kmemleak_object::jiffies whenever the object has been modified (see
> update_checksum()), that will ignore recently changed objects. As
> rcu_head should be updated, that is going to automagically ignore
> those deferred to RCU objects.
This looks the simplest, reset the jiffies every time it detected the
object being touched. However, I wonder whether we should introduce a
new variable to track this. 'jiffies' currently stores the creation time
(or thereabouts). We can change the 'age' reported in the sysfs as long
as no user script parses that.
I added the min age to kmemleak to avoid the early object being added to
some lists and getting reported as false positive. It looks like we have
a similar scenario when the object is getting freed: it is added to RCU
lists, disappears temporarily from kmemleak's view. So it does make
sense to employ similar delay as for creation.
That said, for the default kmemleak operation with scanning every 10min,
this wouldn't be needed. During one scan it detects the checksum changed
due to the rcu_head update. 10min later it should have been freed
already.
--
Catalin
next prev parent reply other threads:[~2024-07-08 11:05 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-17 14:24 [TEST] TCP MD5 vs kmemleak Jakub Kicinski
2024-06-18 3:24 ` Dmitry Safonov
2024-06-18 14:40 ` Jakub Kicinski
2024-06-18 16:17 ` Paul E. McKenney
2024-06-18 16:30 ` Paolo Abeni
2024-06-18 16:42 ` Paul E. McKenney
2024-06-18 17:02 ` Jakub Kicinski
2024-06-18 17:04 ` Uladzislau Rezki
2024-06-18 17:47 ` Paul E. McKenney
2024-06-19 0:33 ` Dmitry Safonov
2024-06-20 17:02 ` Paul E. McKenney
2024-07-02 2:08 ` Dmitry Safonov
2024-07-08 11:05 ` Catalin Marinas [this message]
2024-07-08 18:29 ` Paul E. McKenney
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=ZovH7cWlw9SGcWoJ@arm.com \
--to=catalin.marinas@arm.com \
--cc=0x7f454c46@gmail.com \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=paulmck@kernel.org \
--cc=rcu@vger.kernel.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;
as well as URLs for NNTP newsgroup(s).