]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
dtrace: correct probe disable behaviour for syscalls
authorKris Van Hees <kris.van.hees@oracle.com>
Mon, 18 Jan 2016 10:28:30 +0000 (05:28 -0500)
committerNick Alcock <nick.alcock@oracle.com>
Wed, 3 Feb 2016 16:36:30 +0000 (16:36 +0000)
Previously, when both entry and return probes were enabled for a
syscall, upon disabling one of them, the function pointer in the
syscall table would already be reset to the default, removing the
interceptor.  This resulted in an inconsistent state when the
2nd probe would get removed, and could cause a nasty race if one
were to try to enable one of the probes in between.

We now only remove the interceptor when we know the last probe
is being disabled.

Orabug: 22352636
Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
Acked-by: Nick Alcock <nick.alcock@oracle.com>
dtrace/systrace_dev.c

index 8727637a4b73d126d319d20739015e6351d6c917..49ebb4040ce8ceb9931fdf06de57978f925f2eb8 100644 (file)
@@ -131,11 +131,16 @@ void _systrace_disable(void *arg, dtrace_id_t id, void *parg)
 {
        int                     sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
        dtrace_syscalls_t       *sc = &systrace_info->sysent[sysnum];
-       int                     enabled = sc->stsy_entry != DTRACE_IDNONE ||
-                                         sc->stsy_return != DTRACE_IDNONE;
+       int                     enabled =
+                               (sc->stsy_entry != DTRACE_IDNONE ? 1 : 0) +
+                               (sc->stsy_return != DTRACE_IDNONE ? 1 : 0);
        dt_sys_call_t           intercept = get_intercept(sysnum);
 
-       if (enabled)
+       /*
+        * Every syscall can have 2 probes associated with it.  We need to keep
+        * the interceptor in place until the last probe is getting disabled.
+        */
+       if (enabled == 1)
                (void)cmpxchg((uint32_t *)sc->stsy_tblent, (uint32_t)intercept,
                              (uint32_t)sc->stsy_underlying);