All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
From: Mikulas Patocka <mpatocka@redhat.com>
To: Coly Li <colyli@gmail.com>
Cc: Mike Snitzer <msnitzer@redhat.com>,
	Laurence Oberman <loberman@redhat.com>,
	Tao Ma <boyu.mt@taobao.com>, Robin Dong <sanbai@alibaba-inc.com>,
	dm-devel@redhat.com, "Alasdair G. Kergon" <agk@redhat.com>
Subject: Re: [PATCH 2/4] dm stats: support precise timestamps
Date: Mon, 15 Jun 2015 09:04:02 -0400 (EDT)	[thread overview]
Message-ID: <alpine.LRH.2.02.1506150847460.7275@file01.intranet.prod.int.rdu2.redhat.com> (raw)
In-Reply-To: <557C6266.3040008@gmail.com>



On Sun, 14 Jun 2015, Coly Li wrote:

> ? 15/6/10 ??5:21, Mikulas Patocka ??:
> > This patch makes it possible to use precise timestamps with nanosecond
> > granularity in dm statistics.
> >
> > Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
> >
> > ---
> >  Documentation/device-mapper/statistics.txt |   25 ++++-
> >  drivers/md/dm-stats.c                      |  139 +++++++++++++++++++++--------
> >  drivers/md/dm-stats.h                      |    4 
> >  3 files changed, 125 insertions(+), 43 deletions(-)
> >
> > Index: linux-4.1-rc7/drivers/md/dm-stats.c
> > ===================================================================
> > --- linux-4.1-rc7.orig/drivers/md/dm-stats.c	2015-06-08 16:02:27.000000000 +0200
> > +++ linux-4.1-rc7/drivers/md/dm-stats.c	2015-06-08 16:38:43.000000000 +0200
> > @@ -33,13 +33,14 @@ struct dm_stat_percpu {
> >  
> [snip]
> > @@ -560,8 +578,17 @@ void dm_stats_account_io(struct dm_stats
> >  
> >  	rcu_read_lock();
> >  
> > -	list_for_each_entry_rcu(s, &stats->list, list_entry)
> > -		__dm_stat_bio(s, bi_rw, bi_sector, end_sector, end, duration, stats_aux);
> > +	got_precise_time = false;
> > +	list_for_each_entry_rcu(s, &stats->list, list_entry) {
> > +		if (s->stat_flags & STAT_PRECISE_TIMESTAMPS && !got_precise_time) {
> > +			if (!end)
> > +				stats_aux->duration_ns = ktime_to_ns(ktime_get());
> > +			else
> > +				stats_aux->duration_ns = ktime_to_ns(ktime_get()) - stats_aux->duration_ns;
> > +			got_precise_time = true;
> > +		}
> There are many conditions user space processes may query the global
> timer resource frequently. ktime_get() will call spin_lock when
> accessing global timer resource, calling ktime_get() for each list entry
> might introduce locking contention when stats->list is quite large.

The above code doesn't call ktime_get() for each list entry - it calls 
ktime_get() only once, then sets got_precise_time, and doesn't call it 
anymore.

> A satisfied solution might be something like this,
> 
> +    now = ktime_to_ns(ktime_get());
> +    list_for_each_entry_rcu(s, &stats->list, list_entry) {
> +        if (s->stat_flags & STAT_PRECISE_TIMESTAMPS && !got_precise_time) {
> +            if (!end)
> +                stats_aux->duration_ns = now;
> +            else
> +                stats_aux->duration_ns = now - stats_aux->duration_ns;
> +            got_precise_time = true;
> +        }

This is worse that the previous code - this piece of code calls 
ktime_get() even if no list entry requires precise timestamps. The 
previous code called ktime_get() only if there is at least one list entry 
that has STAT_PRECISE_TIMESTAMPS set.

> In this case the global timer could be access only once, locking
> contention should be much less. Yes, it looks to be some inaccurate, but
> for hard disk I/O latency measurement, the difference almost could be
> ignored.
> > +		__dm_stat_bio(s, bi_rw, bi_sector, end_sector, end, duration_jiffies, stats_aux);
> > +	}
> >  
> >  	rcu_read_unlock();
> >  }
> [snip]
> > @@ -772,21 +803,31 @@ static int message_stats_create(struct m
> >  	unsigned long long start, end, len, step;
> >  	unsigned divisor;
> >  	const char *program_id, *aux_data;
> > +	unsigned stat_flags = 0;
> > +
> > +	struct dm_arg_set as, as_backup;
> > +	const char *a;
> > +	unsigned feature_args;
> >  
> >  	/*
> >  	 * Input format:
> > -	 *   <range> <step> [<program_id> [<aux_data>]]
> > +	 *   <range> <step> [<extra_parameters> <parameters>] [<program_id> [<aux_data>]]
> >  	 */
> >  
> > -	if (argc < 3 || argc > 5)
> > +	if (argc < 3)
> >  		return -EINVAL;
> >  
> > -	if (!strcmp(argv[1], "-")) {
> > +	as.argc = argc;
> > +	as.argv = argv;
> > +	dm_consume_args(&as, 1);
> > +
> > +	a = dm_shift_arg(&as);
> > +	if (!strcmp(a, "-")) {
> >  		start = 0;
> >  		len = dm_get_size(md);
> >  		if (!len)
> >  			len = 1;
> > -	} else if (sscanf(argv[1], "%llu+%llu%c", &start, &len, &dummy) != 2 ||
> > +	} else if (sscanf(a, "%llu+%llu%c", &start, &len, &dummy) != 2 ||
> >  		   start != (sector_t)start || len != (sector_t)len)
> >  		return -EINVAL;
> >  
> > @@ -794,7 +835,8 @@ static int message_stats_create(struct m
> >  	if (start >= end)
> >  		return -EINVAL;
> >  
> > -	if (sscanf(argv[2], "/%u%c", &divisor, &dummy) == 1) {
> > +	a = dm_shift_arg(&as);
> > +	if (sscanf(a, "/%u%c", &divisor, &dummy) == 1) {
> >  		if (!divisor)
> >  			return -EINVAL;
> >  		step = end - start;
> > @@ -802,18 +844,39 @@ static int message_stats_create(struct m
> >  			step++;
> >  		if (!step)
> >  			step = 1;
> > -	} else if (sscanf(argv[2], "%llu%c", &step, &dummy) != 1 ||
> > +	} else if (sscanf(a, "%llu%c", &step, &dummy) != 1 ||
> >  		   step != (sector_t)step || !step)
> >  		return -EINVAL;
> >  
> > +	as_backup = as;
> > +	a = dm_shift_arg(&as);
> > +	if (a && sscanf(a, "%u%c", &feature_args, &dummy) == 1) {
> > +		while (feature_args--) {
> > +			a = dm_shift_arg(&as);
> > +			if (!a)
> > +				return -EINVAL;
> > +			if (!strcasecmp(a, "precise_timestamps"))
> > +				stat_flags |= STAT_PRECISE_TIMESTAMPS;
> > +			else
> > +				return -EINVAL;
> > +		}
> > +	} else {
> > +		as = as_backup;
> > +	}
> > +
> >  	program_id = "-";
> >  	aux_data = "-";
> >  
> > -	if (argc > 3)
> > -		program_id = argv[3];
> > +	a = dm_shift_arg(&as);
> > +	if (a)
> > +		program_id = a;
> > +
> > +	a = dm_shift_arg(&as);
> > +	if (a)
> > +		aux_data = a;
> >  
> > -	if (argc > 4)
> > -		aux_data = argv[4];
> > +	if (as.argc)
> > +		return -EINVAL;
> >  
> If I could, I would simplify the design to remove the above changes in
> message_stats_create(). Just my suggestion ...

I don't know what you mean - if you remove the above changes in 
message_stats_create - then obviously - the user will not be able to 
enable precise timestamps or histogram.

Mikulas

> [snip]
> 
> Coly
> 

  reply	other threads:[~2015-06-15 13:04 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-09 21:20 [PATCH 0/4] Integrate dm-latency functionality to dm-statistics Mikulas Patocka
2015-06-09 21:21 ` [PATCH 1/4] dm-statistics: better argument validation Mikulas Patocka
2015-06-09 21:21 ` [PATCH 2/4] dm stats: support precise timestamps Mikulas Patocka
2015-06-10 17:10   ` Mike Snitzer
2015-06-10 17:33     ` Mikulas Patocka
2015-06-10 17:40       ` Mike Snitzer
2015-06-13 17:03   ` Coly Li
2015-06-15 13:04     ` Mikulas Patocka [this message]
2015-06-15 14:17       ` Coly Li
2015-06-16 15:33   ` Vivek Goyal
2015-06-16 19:27     ` Mikulas Patocka
2015-06-17  1:43       ` Vivek Goyal
2015-06-17 13:17         ` Mikulas Patocka
2015-06-17 13:20           ` Vivek Goyal
2015-06-17 15:18             ` Bryn M. Reeves
2015-06-17 14:54           ` Bryn M. Reeves
2015-06-17 14:52         ` Bryn M. Reeves
2015-07-27 15:11   ` Bryn M. Reeves
2015-06-09 21:22 ` [PATCH 3/4] dm stats: report histogram of latencies Mikulas Patocka
2015-06-13 17:03   ` Coly Li
2015-06-15 13:06     ` Mikulas Patocka
2015-06-15 14:41       ` Coly Li
2015-06-15 15:34         ` Mikulas Patocka
2015-06-16 16:21   ` Vivek Goyal
2015-06-09 21:22 ` [PATCH 4/4] dm stats: support statistics on requests-based devices Mikulas Patocka
2015-06-09 21:23   ` Laurence Oberman
2015-06-13 17:02 ` [PATCH 0/4] Integrate dm-latency functionality to dm-statistics Coly Li
2015-06-15 12:47   ` Mikulas Patocka
2015-06-15 14:35     ` Coly Li
2015-06-17 13:22       ` Mikulas Patocka

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=alpine.LRH.2.02.1506150847460.7275@file01.intranet.prod.int.rdu2.redhat.com \
    --to=mpatocka@redhat.com \
    --cc=agk@redhat.com \
    --cc=boyu.mt@taobao.com \
    --cc=colyli@gmail.com \
    --cc=dm-devel@redhat.com \
    --cc=loberman@redhat.com \
    --cc=msnitzer@redhat.com \
    --cc=sanbai@alibaba-inc.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.