Re: perf_counters issue with self-sampling threads

From: stephane eranian
Date: Wed Jul 29 2009 - 08:37:23 EST


Peter,

On Wed, Jul 29, 2009 at 2:19 PM, Peter Zijlstra<a.p.zijlstra@xxxxxxxxx> wrote:
> On Mon, 2009-07-27 at 18:51 +0200, stephane eranian wrote:
>> I believe there is a problem with the current perf_counters (PCL)
>> code for self-sampling threads. The problem is related to sample
>> notifications via signal.
>>
>> PCL (just like perfmon) is using SIGIO, an asynchronous signal,
>> to notify user applications of the availability of data in the event
>> buffer.
>>
>> POSIX does not mandate that asynchronous signals be delivered
>> to the thread in which they originated. Any thread in the process
>> may process the signal, assuming it does not have the signal
>> blocked.
>
> This signal stuff makes my head spin a little, however:
>
> fcntl(2) for F_SETOWN says:
>
> If a non-zero value is given to F_SETSIG Âin Âa Âmultiâ threaded
> process running with a threading library that supports thread groups
> (e.g., NPTL), Âthen Âa Âpositive value Âgiven Âto ÂF_SETOWN Âhas Âa
> different Âmeaning: instead of being a process ID identifying a whole
> proâ cess, Âit Âis a thread ID identifying a specific thread within a
> process. ÂConsequently, it may be necessary to pass ÂF_SETOWN Âthe
> result of gettid(2) instead of getâ pid(2) to get sensible results
> when F_SETSIG Âis Âused. Â(In Âcurrent ÂLinux Âthreading
> implementations, a main threadâs thread ID is the same as its process
> ID. ÂThis means Âthat Âa Âsingle-threaded program can equally use
> gettid(2) or getpid(2) in this scenario.) Â Note, Âhowâ ever, Âthat
> the Âstatements Âin Âthis paragraph do not apply to the SIGURG signal
> generated Âfor Âout-of-band data Âon a socket: this signal is always
> sent to either a process or a process group, depending Âon Âthe Âvalue
> given Âto ÂF_SETOWN. Â Note Âalso Âthat Linux imposes a limit on the
> number of real-time signals Âthat Âmay Âbe queued Âto Âa Âprocess (see
> getrlimit(2) and signal(7)) and if this limit is reached, then the
> kernel Âreverts to Âdelivering ÂSIGIO, Âand this signal is delivered
> to the entire process rather than to a specific thread.
>
>
> Which seems to imply that when we feed fcntl(F_SETOWN) a TID instead of
> a PID it should deliver SIGIO to the thread instead of the whole process
> -- which, to me, seems a sane semantic.
>
Yes, I remember that manpage. I got the same impression and in fact that is
what I document in some of my test programs. So you read this right.

> However,
>
> Âkill_fasync(SIGIO)
> Â Â__kill_fasync()
> Â Â Âsend_sigio()
> Â Â Â Â/* if pid_type is a PIDTYPE_PID and pid a TID this should
> Â Â Â Â Â only iterate the one thread, I think */
> Â Â Â Âdo_each_pid_task() {
> Â Â Â Â Âsend_sigio_to_task();
> Â Â Â Â} while_each_pid_task();
>
> where:
>
> Âsend_sigio_to_task()
> Â Âgroup_send_sig_info()
> Â Â Â__group_send_sig_info()
> Â Â Â Âsend_signal(.group = 1) /* uh-ow trouble */
> Â Â Â Â Â__send_signal()
> Â Â Â Â Â Âif (group)
> Â Â Â Â Â Â Â pending = &t->signal->shared_pending
>
> which will result in the signal being send to the whole process anyway.
>
Exactly! That is the code path and this is why this does not work as
expected. Nowhere along that path is there special casing for that
F_SETOWN of tid vs. pid. kill_fasync() implies group.


>
> Now I was considering teaching send_sigio_to_task() to use
> specific_send_sig_info() when fown->pid != fown->group_leader->pid or
> something, but I'm not sure that won't break anything.
>
Yes, that's the problem with touching this. I don't know if this will break
things. That's why I was suggested creating a parallel code path which
does what we want without modifying the existing path. Unless you know
some signal expert at redhat or elsewhere.

> Alternatively, I've missed a detail and I either read the manpage wrong,
> or the code, or both of them.
>
The code does not correspond to the manpage. Not clear which one
is correct though. This F_SETOWN trick looks very Linux specific.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/