]> sourceware.org Git - systemtap.git/commitdiff
Improve PR20600 by adding might_sleep() calls in the runtime.
authorDavid Smith <dsmith@redhat.com>
Wed, 19 Oct 2016 15:23:53 +0000 (10:23 -0500)
committerDavid Smith <dsmith@redhat.com>
Wed, 19 Oct 2016 15:23:53 +0000 (10:23 -0500)
* runtime/linux/runtime_context.h (_stp_runtime_entryfn_get_context): Add
  comment about not re-enabling preemption.
* runtime/linux/kprobes.c: Add a few might_sleep() calls.
* runtime/linux/stp_tracepoint.c: Ditto.
* runtime/linux/uprobes-common.c: Ditto.
* runtime/linux/uprobes-inode.c (stapiu_target_lock): Ditto.
* runtime/transport/control.c (_stp_ctl_write_cmd): Ditto.
* runtime/transport/transport.c: Ditto.
* translate.cxx (emit_module_init): Ditto.
* runtime/time.c (_stp_init_time): Ditto.

runtime/linux/kprobes.c
runtime/linux/runtime_context.h
runtime/linux/stp_tracepoint.c
runtime/linux/uprobes-common.c
runtime/linux/uprobes-inode.c
runtime/time.c
runtime/transport/control.c
runtime/transport/transport.c
translate.cxx

index 72db8c7a6b5aa233174ad5bee9b382e07fd9dc52..ebc6c69d5344530c868987be2dc0aaa935f3e352 100644 (file)
@@ -728,6 +728,7 @@ stapkp_init(struct stap_kprobe_probe *probes,
       sd.nprobes = nprobes;
       sd.probe_max = probe_max;
       sd.modname = NULL;
+      might_sleep();
       mutex_lock(&module_mutex);
       kallsyms_on_each_symbol(stapkp_symbol_callback, &sd);
       mutex_unlock(&module_mutex);
@@ -794,6 +795,7 @@ stapkp_refresh(const char *modname,
         sd.nprobes = nprobes;
         sd.probe_max = probe_max;
         sd.modname = modname;
+        might_sleep();
         mutex_lock(&module_mutex);
         kallsyms_on_each_symbol(stapkp_symbol_callback, &sd);
         mutex_unlock(&module_mutex);
index b81f5becd156e95a2998046440f90ae38a5351a2..48894a6d63232777e84b37eb7351c94fc36ae9c5 100644 (file)
@@ -82,8 +82,14 @@ static struct context * _stp_runtime_entryfn_get_context(void)
        preempt_disable ();
        c = _stp_runtime_get_context();
        if (c != NULL) {
-               if (atomic_inc_return(&c->busy) == 1)
+               if (atomic_inc_return(&c->busy) == 1) {
+                       // NB: Notice we're not re-enabling preemption
+                       // here. We exepect the calling code to call
+                       // _stp_runtime_entryfn_get_context() and
+                       // _stp_runtime_entryfn_put_context() as a
+                       // pair.
                        return c;
+               }
                atomic_dec(&c->busy);
        }
        preempt_enable_no_resched();
index 33fe27aaae07ee7b1165a12b57be207e4fc8ca45..4281ec1241aefff598b589c271ee1a1d0fb40c89 100644 (file)
@@ -207,6 +207,7 @@ int stp_tracepoint_probe_register(const char *name, void *probe, void *data)
        struct tracepoint_entry *e;
        int ret = 0;
 
+       might_sleep();
        mutex_lock(&stp_tracepoint_mutex);
        e = get_tracepoint(name);
        if (!e) {
@@ -238,6 +239,7 @@ int stp_tracepoint_probe_unregister(const char *name, void *probe, void *data)
        struct tracepoint_entry *e;
        int ret = 0;
 
+       might_sleep();
        mutex_lock(&stp_tracepoint_mutex);
        e = get_tracepoint(name);
        if (!e) {
@@ -269,6 +271,7 @@ int stp_tracepoint_coming(struct tp_module *tp_mod)
 {
        int i;
 
+       might_sleep();
        mutex_lock(&stp_tracepoint_mutex);
        for (i = 0; i < tp_mod->mod->num_tracepoints; i++) {
                struct tracepoint *tp;
@@ -310,6 +313,7 @@ int stp_tracepoint_going(struct tp_module *tp_mod)
 {
        int i;
 
+       might_sleep();
        mutex_lock(&stp_tracepoint_mutex);
        for (i = 0; i < tp_mod->mod->num_tracepoints; i++) {
                struct tracepoint *tp;
@@ -394,6 +398,7 @@ void stp_kernel_tracepoint_add(struct tracepoint *tp, void *priv)
        struct stp_tp_probe *p;
        int *ret = priv;
 
+       might_sleep();
        mutex_lock(&stp_tracepoint_mutex);
        e = get_tracepoint(tp->name);
        if (!e) {
@@ -430,6 +435,7 @@ void stp_kernel_tracepoint_remove(struct tracepoint *tp, void *priv)
        struct tracepoint_entry *e;
        int *ret = priv;
 
+       might_sleep();
        mutex_lock(&stp_tracepoint_mutex);
        e = get_tracepoint(tp->name);
        if (!e || e->refcount != 1 || !list_empty(&e->probes)) {
@@ -465,6 +471,7 @@ void stp_tracepoint_exit(void)
 
        stp_tracepoint_module_exit();
        for_each_kernel_tracepoint(stp_kernel_tracepoint_remove, &ret);
+       might_sleep();
        mutex_lock(&stp_tracepoint_mutex);
        for (i = 0; i < TRACEPOINT_TABLE_SIZE; i++) {
                struct hlist_head *head = &tracepoint_table[i];
index db20ab5198fb8919d5a86995500d7ffa00ec395a..50db6acf23cf8a798a048727844a47ccb2a08af5 100644 (file)
@@ -45,6 +45,7 @@ static int stap_uprobe_change_plus (struct task_struct *tsk, unsigned long reloc
        stap_uprobes[] array to allocate a free spot, but then we can
        unlock and do the register_*probe subsequently. */
 
+    might_sleep();
     mutex_lock (& stap_uprobes_lock);
     for (i=0; i<MAXUPROBES; i++) { /* XXX: slow linear search */
       sup = & stap_uprobes[i];
@@ -118,6 +119,7 @@ static int stap_uprobe_change_plus (struct task_struct *tsk, unsigned long reloc
         _stp_warn ("u*probe failed %s[%d] '%s' addr %p rc %d\n", tsk->comm, tsk->tgid, sups->probe->pp, (void*)(relocation + sups->address), rc);
        /* NB: we need to release this slot,
           so we need to borrow the mutex temporarily. */
+       might_sleep();
         mutex_lock (& stap_uprobes_lock);
         sup->spec_index = -1;
        sup->sdt_sem_address = 0;
@@ -204,6 +206,7 @@ static int stap_uprobe_change_minus (struct task_struct *tsk, unsigned long relo
     struct stap_uprobe_spec *sups;
     if (sup->spec_index < 0) continue; /* skip free uprobes slot */
     sups = (struct stap_uprobe_spec*) & stap_uprobe_specs[sup->spec_index];
+    might_sleep();
     mutex_lock (& stap_uprobes_lock);
 
     /* PR6829, PR9940:
index caf7ce885cf6764e53d5b4eeaa54937678c21e82..7c874c2cbe0f1d0d5a38da18fb56f3b1f26c85d6 100644 (file)
@@ -235,6 +235,7 @@ stapiu_unregister (struct inode* inode, struct stapiu_consumer* c)
 static inline void
 stapiu_target_lock(struct stapiu_target *target)
 {
+       might_sleep();
        mutex_lock(&target->inode_lock);
 }
 
index 10bb2aab7217e6a615c005342f49236d543a0434..0bd9e4fe76445f6baad84e8a581c73b432bec4d5 100644 (file)
@@ -304,6 +304,7 @@ _stp_init_time(void)
 {
     int cpu, ret = 0;
 
+    might_sleep();
     _stp_kill_time();
 
     stp_time = _stp_alloc_percpu(sizeof(stp_time_t));
index d5c3f1ef29888dcd48eb2c3b4cb6a99d1f7dd16f..d9ed6b453454f8a8f3e400870a0c2e9c9edaf632 100644 (file)
@@ -63,6 +63,7 @@ static ssize_t _stp_ctl_write_cmd(struct file *file, const char __user *buf, siz
 
         // PR17232: preclude reentrancy during handling of messages.
         // This also permits use of static variables in the switch/case.
+       might_sleep();
         mutex_lock (& cmd_mutex);
         // NB: past this point, no 'return;' - use 'goto out;'
 
index 179a2ba357416bfe2ecf8aff7353286284735e58..3400f220acb9a2454eeb4fb0cca9d728b8b5482c 100644 (file)
@@ -503,6 +503,7 @@ static inline void _stp_lock_inode(struct inode *inode)
        inode_lock(inode);
 #else
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
+       might_sleep();
        mutex_lock(&inode->i_mutex);
 #else
        down(&inode->i_sem);
index 21afccda0236739bd51df625c4c3680e50a42746..bd71e60c83a4a9b0cb55da599965911b95aaf0ba 100644 (file)
@@ -1793,6 +1793,11 @@ c_unparser::emit_module_init ()
       o->newline() << "const char* version = UTS_VERSION;";
       o->newline() << "#endif";
 
+      // The systemtap_module_init() function must be run in
+      // non-atomic context, since several functions might need to
+      // sleep.
+      o->newline() << "might_sleep();";
+
       // NB: This UTS_RELEASE compile-time macro directly checks only that
       // the compile-time kbuild tree matches the compile-time debuginfo/etc.
       // It does not check the run time kernel value.  However, this is
This page took 0.065874 seconds and 5 git commands to generate.