mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Paul Mackerras <paulus@samba.org>
To: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>,
	linux-kernel@vger.kernel.org, Mike Galbraith <efault@gmx.de>,
	Arjan van de Ven <arjan@infradead.org>,
	Wu Fengguang <fengguang.wu@intel.com>
Subject: Re: [PATCH 2/9] perf_counter: fix update_userpage()
Date: Sun, 29 Mar 2009 11:24:28 +1100	[thread overview]
Message-ID: <18894.49084.341238.775487@cargo.ozlabs.ibm.com> (raw)
In-Reply-To: <20090328194929.546464621@chello.nl>

Peter Zijlstra writes:

> It just occured to me it is possible to have multiple contending
> updates of the userpage (mmap information vs overflow vs counter).
> This would break the seqlock logic.
> 
> It appear the arch code uses this from NMI context, so we cannot
> possibly serialize its use, therefore separate the data_head update
> from it and let it return to its original use.

That sounds reasonable, and thanks for putting in a big comment.

Acked-by: Paul Mackerras <paulus@samba.org>

> --- linux-2.6.orig/include/linux/perf_counter.h
> +++ linux-2.6/include/linux/perf_counter.h
> @@ -160,10 +160,45 @@ struct perf_counter_hw_event {
>  struct perf_counter_mmap_page {
>  	__u32	version;		/* version number of this structure */
>  	__u32	compat_version;		/* lowest version this is compat with */
> +
> +	/*
> +	 * Bits needed to read the hw counters in user-space.
> +	 *
> +	 * The index and offset should be read atomically using the seqlock:
> +	 *
> +	 *   __u32 seq, index;
> +	 *   __s64 offset;
> +	 *
> +	 * again:
> +	 *   rmb();
> +	 *   seq = pc->lock;
> +	 *
> +	 *   if (unlikely(seq & 1)) {
> +	 *     cpu_relax();
> +	 *     goto again;
> +	 *   }
> +	 *
> +	 *   index = pc->index;
> +	 *   offset = pc->offset;
> +	 *
> +	 *   rmb();
> +	 *   if (pc->lock != seq)
> +	 *     goto again;
> +	 *
> +	 * After this, index contains architecture specific counter index + 1,
> +	 * so that 0 means unavailable, offset contains the value to be added
> +	 * to the result of the raw timer read to obtain this counter's value.
> +	 */
>  	__u32	lock;			/* seqlock for synchronization */
>  	__u32	index;			/* hardware counter identifier */
>  	__s64	offset;			/* add to hardware counter value */

I think we can simplify this (in a follow-on patch).

It has occurred to me that we don't need to do all this on the
userspace side, because we are necessarily reading and writing these
fields on the same CPU.  If the reader and writer were on different
CPUs, that would make no sense since they would be accessing different
hardware counter registers.

That means that we don't need any CPU memory barriers on either side.
All the kernel needs to do is to increment `lock' when it updates
things, and the user side can be:

	do {
		seq = pc->lock;
		index = pc->index;
		offset = pc->offset;
		barrier();
	} while (pc->lock != seq);

and all that's needed is a compiler barrier to stop the compiler from
optimizing too much.

Paul.

  reply	other threads:[~2009-03-29  0:25 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-28 19:43 [PATCH 0/9] perf_counter patches Peter Zijlstra
2009-03-28 19:44 ` [PATCH 1/9] perf_counter: unify and fix delayed counter wakeup Peter Zijlstra
2009-03-29  0:14   ` Paul Mackerras
2009-03-29  9:16     ` Peter Zijlstra
2009-03-29  9:25       ` Peter Zijlstra
2009-03-29 10:02         ` Paul Mackerras
2009-03-28 19:44 ` [PATCH 2/9] perf_counter: fix update_userpage() Peter Zijlstra
2009-03-29  0:24   ` Paul Mackerras [this message]
2009-04-02  8:50     ` Peter Zijlstra
2009-04-02  9:00       ` Peter Zijlstra
2009-04-02  9:21         ` Paul Mackerras
2009-04-02  9:28           ` Peter Zijlstra
2009-04-02  9:15       ` Paul Mackerras
2009-04-02  9:36         ` Peter Zijlstra
2009-04-02  9:58           ` Paul Mackerras
2009-04-02 10:36             ` Peter Zijlstra
2009-03-28 19:44 ` [PATCH 3/9] perf_counter: kerneltop: simplify data_head read Peter Zijlstra
2009-03-28 19:44 ` [PATCH 4/9] perf_counter: executable mmap() information Peter Zijlstra
2009-03-28 19:44 ` [PATCH 5/9] perf_counter: kerneltop: parse the mmap data stream Peter Zijlstra
2009-03-28 19:44 ` [PATCH 6/9] perf_counter: powerpc: only reserve PMU hardware when we need it Peter Zijlstra
2009-03-28 19:44 ` [PATCH 7/9] perf_counter: make it possible for hw_perf_counter_init to return error codes Peter Zijlstra
2009-03-30  4:13   ` Paul Mackerras
2009-03-28 19:44 ` [PATCH 8/9] perf_counter tools: optionally scale counter values in perfstat mode Peter Zijlstra
2009-03-28 19:44 ` [PATCH 9/9] RFC perf_counter: event overlow handling Peter Zijlstra

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=18894.49084.341238.775487@cargo.ozlabs.ibm.com \
    --to=paulus@samba.org \
    --cc=a.p.zijlstra@chello.nl \
    --cc=arjan@infradead.org \
    --cc=efault@gmx.de \
    --cc=fengguang.wu@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    /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

all inboxes | Powered by JetHome®