All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andi Shyti <andi.shyti@linux.intel.com>
To: Andrzej Hajda <andrzej.hajda@intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>,
	Joonas Lahtinen <joonas.lahtinen@linux.intel.com>,
	Rodrigo Vivi <rodrigo.vivi@intel.com>,
	Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>,
	David Airlie <airlied@gmail.com>, Daniel Vetter <daniel@ffwll.ch>,
	linux-kernel@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org,
	Chris Wilson <chris@chris-wilson.co.uk>,
	netdev@vger.kernel.org, Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>,
	Dmitry Vyukov <dvyukov@google.com>,
	"David S. Miller" <davem@davemloft.net>,
	Andi Shyti <andi.shyti@linux.intel.com>
Subject: Re: [PATCH v6 2/8] lib/ref_tracker: improve printing stats
Date: Wed, 29 Mar 2023 14:51:37 +0200	[thread overview]
Message-ID: <ZCQ0WSnZ9L2NFsvA@ashyti-mobl2.lan> (raw)
In-Reply-To: <20230224-track_gt-v6-2-0dc8601fd02f@intel.com>

Hi Andrzej,

[...]

> -void ref_tracker_dir_print_locked(struct ref_tracker_dir *dir,
> -				  unsigned int display_limit)
> +struct ref_tracker_dir_stats {
> +	int total;
> +	int count;
> +	struct {
> +		depot_stack_handle_t stack_handle;
> +		unsigned int count;
> +	} stacks[];
> +};
> +
> +static struct ref_tracker_dir_stats *
> +ref_tracker_get_stats(struct ref_tracker_dir *dir, unsigned int limit)
>  {
> +	struct ref_tracker_dir_stats *stats;
>  	struct ref_tracker *tracker;
> -	unsigned int i = 0;
>  
> -	lockdep_assert_held(&dir->lock);
> +	stats = kmalloc(struct_size(stats, stacks, limit),
> +			GFP_NOWAIT | __GFP_NOWARN);
> +	if (!stats)
> +		return ERR_PTR(-ENOMEM);
> +	stats->total = 0;
> +	stats->count = 0;
>  
>  	list_for_each_entry(tracker, &dir->list, head) {
> -		if (i < display_limit) {
> -			pr_err("leaked reference.\n");
> -			if (tracker->alloc_stack_handle)
> -				stack_depot_print(tracker->alloc_stack_handle);
> -			i++;
> -		} else {
> -			break;
> +		depot_stack_handle_t stack = tracker->alloc_stack_handle;
> +		int i;
> +
> +		++stats->total;
> +		for (i = 0; i < stats->count; ++i)
> +			if (stats->stacks[i].stack_handle == stack)
> +				break;
> +		if (i >= limit)
> +			continue;
> +		if (i >= stats->count) {
> +			stats->stacks[i].stack_handle = stack;
> +			stats->stacks[i].count = 0;
> +			++stats->count;
>  		}
> +		++stats->stacks[i].count;
> +	}
> +
> +	return stats;
> +}
> +
> +void ref_tracker_dir_print_locked(struct ref_tracker_dir *dir,
> +				  unsigned int display_limit)
> +{
> +	struct ref_tracker_dir_stats *stats;
> +	unsigned int i = 0, skipped;
> +	depot_stack_handle_t stack;
> +	char *sbuf;
> +
> +	lockdep_assert_held(&dir->lock);
> +
> +	if (list_empty(&dir->list))
> +		return;
> +
> +	stats = ref_tracker_get_stats(dir, display_limit);
> +	if (IS_ERR(stats)) {
> +		pr_err("%s@%pK: couldn't get stats, error %pe\n",
> +		       dir->name, dir, stats);
> +		return;
>  	}
> +
> +	sbuf = kmalloc(STACK_BUF_SIZE, GFP_NOWAIT | __GFP_NOWARN);
> +
> +	for (i = 0, skipped = stats->total; i < stats->count; ++i) {
> +		stack = stats->stacks[i].stack_handle;
> +		if (sbuf && !stack_depot_snprint(stack, sbuf, STACK_BUF_SIZE, 4))
> +			sbuf[0] = 0;
> +		pr_err("%s@%pK has %d/%d users at\n%s\n", dir->name, dir,
> +		       stats->stacks[i].count, stats->total, sbuf);
> +		skipped -= stats->stacks[i].count;
> +	}
> +
> +	if (skipped)
> +		pr_err("%s@%pK skipped reports about %d/%d users.\n",
> +		       dir->name, dir, skipped, stats->total);
> +
> +	kfree(sbuf);
> +
> +	kfree(stats);

There's a chance of confusion here because
ref_tracker_get_stats() might need a ref_tracker_put_stats() to
go with it.

When you allocate in one function and free in another without a
clear pair (get/put, alloc/free, etc.), it can be hard to notice
and could lead to mistakes.

But in this simple situation, it's not a big problem, and I'm not
sure if having the put side is really needed.

Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com> 

Thanks,
Andi

>  }
>  EXPORT_SYMBOL(ref_tracker_dir_print_locked);
>  
> 
> -- 
> 2.34.1

WARNING: multiple messages have this Message-ID (diff)
From: Andi Shyti <andi.shyti@linux.intel.com>
To: Andrzej Hajda <andrzej.hajda@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>,
	Andi Shyti <andi.shyti@linux.intel.com>,
	netdev@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	linux-kernel@vger.kernel.org,
	Chris Wilson <chris@chris-wilson.co.uk>,
	Eric Dumazet <edumazet@google.com>,
	dri-devel@lists.freedesktop.org,
	Rodrigo Vivi <rodrigo.vivi@intel.com>,
	Jakub Kicinski <kuba@kernel.org>,
	"David S. Miller" <davem@davemloft.net>,
	Dmitry Vyukov <dvyukov@google.com>
Subject: Re: [PATCH v6 2/8] lib/ref_tracker: improve printing stats
Date: Wed, 29 Mar 2023 14:51:37 +0200	[thread overview]
Message-ID: <ZCQ0WSnZ9L2NFsvA@ashyti-mobl2.lan> (raw)
In-Reply-To: <20230224-track_gt-v6-2-0dc8601fd02f@intel.com>

Hi Andrzej,

[...]

> -void ref_tracker_dir_print_locked(struct ref_tracker_dir *dir,
> -				  unsigned int display_limit)
> +struct ref_tracker_dir_stats {
> +	int total;
> +	int count;
> +	struct {
> +		depot_stack_handle_t stack_handle;
> +		unsigned int count;
> +	} stacks[];
> +};
> +
> +static struct ref_tracker_dir_stats *
> +ref_tracker_get_stats(struct ref_tracker_dir *dir, unsigned int limit)
>  {
> +	struct ref_tracker_dir_stats *stats;
>  	struct ref_tracker *tracker;
> -	unsigned int i = 0;
>  
> -	lockdep_assert_held(&dir->lock);
> +	stats = kmalloc(struct_size(stats, stacks, limit),
> +			GFP_NOWAIT | __GFP_NOWARN);
> +	if (!stats)
> +		return ERR_PTR(-ENOMEM);
> +	stats->total = 0;
> +	stats->count = 0;
>  
>  	list_for_each_entry(tracker, &dir->list, head) {
> -		if (i < display_limit) {
> -			pr_err("leaked reference.\n");
> -			if (tracker->alloc_stack_handle)
> -				stack_depot_print(tracker->alloc_stack_handle);
> -			i++;
> -		} else {
> -			break;
> +		depot_stack_handle_t stack = tracker->alloc_stack_handle;
> +		int i;
> +
> +		++stats->total;
> +		for (i = 0; i < stats->count; ++i)
> +			if (stats->stacks[i].stack_handle == stack)
> +				break;
> +		if (i >= limit)
> +			continue;
> +		if (i >= stats->count) {
> +			stats->stacks[i].stack_handle = stack;
> +			stats->stacks[i].count = 0;
> +			++stats->count;
>  		}
> +		++stats->stacks[i].count;
> +	}
> +
> +	return stats;
> +}
> +
> +void ref_tracker_dir_print_locked(struct ref_tracker_dir *dir,
> +				  unsigned int display_limit)
> +{
> +	struct ref_tracker_dir_stats *stats;
> +	unsigned int i = 0, skipped;
> +	depot_stack_handle_t stack;
> +	char *sbuf;
> +
> +	lockdep_assert_held(&dir->lock);
> +
> +	if (list_empty(&dir->list))
> +		return;
> +
> +	stats = ref_tracker_get_stats(dir, display_limit);
> +	if (IS_ERR(stats)) {
> +		pr_err("%s@%pK: couldn't get stats, error %pe\n",
> +		       dir->name, dir, stats);
> +		return;
>  	}
> +
> +	sbuf = kmalloc(STACK_BUF_SIZE, GFP_NOWAIT | __GFP_NOWARN);
> +
> +	for (i = 0, skipped = stats->total; i < stats->count; ++i) {
> +		stack = stats->stacks[i].stack_handle;
> +		if (sbuf && !stack_depot_snprint(stack, sbuf, STACK_BUF_SIZE, 4))
> +			sbuf[0] = 0;
> +		pr_err("%s@%pK has %d/%d users at\n%s\n", dir->name, dir,
> +		       stats->stacks[i].count, stats->total, sbuf);
> +		skipped -= stats->stacks[i].count;
> +	}
> +
> +	if (skipped)
> +		pr_err("%s@%pK skipped reports about %d/%d users.\n",
> +		       dir->name, dir, skipped, stats->total);
> +
> +	kfree(sbuf);
> +
> +	kfree(stats);

There's a chance of confusion here because
ref_tracker_get_stats() might need a ref_tracker_put_stats() to
go with it.

When you allocate in one function and free in another without a
clear pair (get/put, alloc/free, etc.), it can be hard to notice
and could lead to mistakes.

But in this simple situation, it's not a big problem, and I'm not
sure if having the put side is really needed.

Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com> 

Thanks,
Andi

>  }
>  EXPORT_SYMBOL(ref_tracker_dir_print_locked);
>  
> 
> -- 
> 2.34.1

WARNING: multiple messages have this Message-ID (diff)
From: Andi Shyti <andi.shyti@linux.intel.com>
To: Andrzej Hajda <andrzej.hajda@intel.com>
Cc: netdev@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	linux-kernel@vger.kernel.org,
	Chris Wilson <chris@chris-wilson.co.uk>,
	Eric Dumazet <edumazet@google.com>,
	dri-devel@lists.freedesktop.org, Daniel Vetter <daniel@ffwll.ch>,
	Rodrigo Vivi <rodrigo.vivi@intel.com>,
	Jakub Kicinski <kuba@kernel.org>,
	David Airlie <airlied@gmail.com>,
	"David S. Miller" <davem@davemloft.net>,
	Dmitry Vyukov <dvyukov@google.com>
Subject: Re: [Intel-gfx] [PATCH v6 2/8] lib/ref_tracker: improve printing stats
Date: Wed, 29 Mar 2023 14:51:37 +0200	[thread overview]
Message-ID: <ZCQ0WSnZ9L2NFsvA@ashyti-mobl2.lan> (raw)
In-Reply-To: <20230224-track_gt-v6-2-0dc8601fd02f@intel.com>

Hi Andrzej,

[...]

> -void ref_tracker_dir_print_locked(struct ref_tracker_dir *dir,
> -				  unsigned int display_limit)
> +struct ref_tracker_dir_stats {
> +	int total;
> +	int count;
> +	struct {
> +		depot_stack_handle_t stack_handle;
> +		unsigned int count;
> +	} stacks[];
> +};
> +
> +static struct ref_tracker_dir_stats *
> +ref_tracker_get_stats(struct ref_tracker_dir *dir, unsigned int limit)
>  {
> +	struct ref_tracker_dir_stats *stats;
>  	struct ref_tracker *tracker;
> -	unsigned int i = 0;
>  
> -	lockdep_assert_held(&dir->lock);
> +	stats = kmalloc(struct_size(stats, stacks, limit),
> +			GFP_NOWAIT | __GFP_NOWARN);
> +	if (!stats)
> +		return ERR_PTR(-ENOMEM);
> +	stats->total = 0;
> +	stats->count = 0;
>  
>  	list_for_each_entry(tracker, &dir->list, head) {
> -		if (i < display_limit) {
> -			pr_err("leaked reference.\n");
> -			if (tracker->alloc_stack_handle)
> -				stack_depot_print(tracker->alloc_stack_handle);
> -			i++;
> -		} else {
> -			break;
> +		depot_stack_handle_t stack = tracker->alloc_stack_handle;
> +		int i;
> +
> +		++stats->total;
> +		for (i = 0; i < stats->count; ++i)
> +			if (stats->stacks[i].stack_handle == stack)
> +				break;
> +		if (i >= limit)
> +			continue;
> +		if (i >= stats->count) {
> +			stats->stacks[i].stack_handle = stack;
> +			stats->stacks[i].count = 0;
> +			++stats->count;
>  		}
> +		++stats->stacks[i].count;
> +	}
> +
> +	return stats;
> +}
> +
> +void ref_tracker_dir_print_locked(struct ref_tracker_dir *dir,
> +				  unsigned int display_limit)
> +{
> +	struct ref_tracker_dir_stats *stats;
> +	unsigned int i = 0, skipped;
> +	depot_stack_handle_t stack;
> +	char *sbuf;
> +
> +	lockdep_assert_held(&dir->lock);
> +
> +	if (list_empty(&dir->list))
> +		return;
> +
> +	stats = ref_tracker_get_stats(dir, display_limit);
> +	if (IS_ERR(stats)) {
> +		pr_err("%s@%pK: couldn't get stats, error %pe\n",
> +		       dir->name, dir, stats);
> +		return;
>  	}
> +
> +	sbuf = kmalloc(STACK_BUF_SIZE, GFP_NOWAIT | __GFP_NOWARN);
> +
> +	for (i = 0, skipped = stats->total; i < stats->count; ++i) {
> +		stack = stats->stacks[i].stack_handle;
> +		if (sbuf && !stack_depot_snprint(stack, sbuf, STACK_BUF_SIZE, 4))
> +			sbuf[0] = 0;
> +		pr_err("%s@%pK has %d/%d users at\n%s\n", dir->name, dir,
> +		       stats->stacks[i].count, stats->total, sbuf);
> +		skipped -= stats->stacks[i].count;
> +	}
> +
> +	if (skipped)
> +		pr_err("%s@%pK skipped reports about %d/%d users.\n",
> +		       dir->name, dir, skipped, stats->total);
> +
> +	kfree(sbuf);
> +
> +	kfree(stats);

There's a chance of confusion here because
ref_tracker_get_stats() might need a ref_tracker_put_stats() to
go with it.

When you allocate in one function and free in another without a
clear pair (get/put, alloc/free, etc.), it can be hard to notice
and could lead to mistakes.

But in this simple situation, it's not a big problem, and I'm not
sure if having the put side is really needed.

Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com> 

Thanks,
Andi

>  }
>  EXPORT_SYMBOL(ref_tracker_dir_print_locked);
>  
> 
> -- 
> 2.34.1

  reply	other threads:[~2023-03-29 12:52 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-29  7:24 [PATCH v6 0/8] drm/i915: use ref_tracker library for tracking wakerefs Andrzej Hajda
2023-03-29  7:24 ` Andrzej Hajda
2023-03-29  7:24 ` [Intel-gfx] " Andrzej Hajda
2023-03-29  7:24 ` [PATCH v6 1/8] lib/ref_tracker: add unlocked leak print helper Andrzej Hajda
2023-03-29  7:24   ` Andrzej Hajda
2023-03-29  7:24   ` [Intel-gfx] " Andrzej Hajda
2023-03-29 12:35   ` Andi Shyti
2023-03-29 12:35     ` [Intel-gfx] " Andi Shyti
2023-03-29 12:35     ` Andi Shyti
2023-03-29  7:24 ` [PATCH v6 2/8] lib/ref_tracker: improve printing stats Andrzej Hajda
2023-03-29  7:24   ` Andrzej Hajda
2023-03-29  7:24   ` [Intel-gfx] " Andrzej Hajda
2023-03-29 12:51   ` Andi Shyti [this message]
2023-03-29 12:51     ` Andi Shyti
2023-03-29 12:51     ` Andi Shyti
2023-03-29  7:24 ` [PATCH v6 3/8] lib/ref_tracker: add printing to memory buffer Andrzej Hajda
2023-03-29  7:24   ` Andrzej Hajda
2023-03-29  7:24   ` [Intel-gfx] " Andrzej Hajda
2023-03-29 12:56   ` Andi Shyti
2023-03-29 12:56     ` [Intel-gfx] " Andi Shyti
2023-03-29 12:56     ` Andi Shyti
2023-03-29  7:24 ` [PATCH v6 4/8] lib/ref_tracker: remove warnings in case of allocation failure Andrzej Hajda
2023-03-29  7:24   ` Andrzej Hajda
2023-03-29  7:24   ` [Intel-gfx] " Andrzej Hajda
2023-03-29  7:24 ` [Intel-gfx] [PATCH v6 5/8] drm/i915: Correct type of wakeref variable Andrzej Hajda
2023-03-29  7:24   ` Andrzej Hajda
2023-03-29  7:24   ` Andrzej Hajda
2023-03-29  7:24 ` [Intel-gfx] [PATCH v6 6/8] drm/i915: Replace custom intel runtime_pm tracker with ref_tracker library Andrzej Hajda
2023-03-29  7:24   ` Andrzej Hajda
2023-03-29  7:24   ` Andrzej Hajda
2023-03-29  7:24 ` [PATCH v6 7/8] drm/i915: track gt pm wakerefs Andrzej Hajda
2023-03-29  7:24   ` Andrzej Hajda
2023-03-29  7:24   ` [Intel-gfx] " Andrzej Hajda
2023-03-29  7:24 ` [PATCH v6 8/8] drm/i915/gt: Hold a wakeref for the active VM Andrzej Hajda
2023-03-29  7:24   ` Andrzej Hajda
2023-03-29  7:24   ` [Intel-gfx] " Andrzej Hajda
2023-03-29 13:01 ` [PATCH v6 0/8] drm/i915: use ref_tracker library for tracking wakerefs Andi Shyti
2023-03-29 13:01   ` [Intel-gfx] " Andi Shyti
2023-03-29 13:01   ` Andi Shyti
2023-03-29 14:03 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: use ref_tracker library for tracking wakerefs (rev7) Patchwork
2023-03-29 14:03 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2023-03-29 14:29 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork

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=ZCQ0WSnZ9L2NFsvA@ashyti-mobl2.lan \
    --to=andi.shyti@linux.intel.com \
    --cc=airlied@gmail.com \
    --cc=andrzej.hajda@intel.com \
    --cc=chris@chris-wilson.co.uk \
    --cc=daniel@ffwll.ch \
    --cc=davem@davemloft.net \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=dvyukov@google.com \
    --cc=edumazet@google.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=jani.nikula@linux.intel.com \
    --cc=joonas.lahtinen@linux.intel.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=rodrigo.vivi@intel.com \
    --cc=tvrtko.ursulin@linux.intel.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.