Skip to content
This repository has been archived by the owner on Feb 26, 2020. It is now read-only.

Commit

Permalink
splat atomic:64-bit: Create thread outside spin lock
Browse files Browse the repository at this point in the history
The Fedora 3.6 debug kernel identified the following issue where
we create a thread under a spin lock.  This isn't safe because
sleeping could result in a deadlock.  Therefore the lock is changed
to a mutex so it's safe to sleep.

  BUG: sleeping function called from invalid context at mm/slub.c:930
  in_atomic(): 1, irqs_disabled(): 0, pid: 10583, name: splat
  1 lock held by splat/10583:

Signed-off-by: Brian Behlendorf <[email protected]>
  • Loading branch information
behlendorf committed Nov 6, 2012
1 parent 0e149d4 commit b8296bf
Showing 1 changed file with 7 additions and 7 deletions.
14 changes: 7 additions & 7 deletions module/splat/splat-atomic.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ typedef enum {
typedef struct atomic_priv {
unsigned long ap_magic;
struct file *ap_file;
spinlock_t ap_lock;
struct mutex ap_lock;
wait_queue_head_t ap_waitq;
volatile uint64_t ap_atomic;
volatile uint64_t ap_atomic_exited;
Expand All @@ -69,10 +69,10 @@ splat_atomic_work(void *priv)
ap = (atomic_priv_t *)priv;
ASSERT(ap->ap_magic == SPLAT_ATOMIC_TEST_MAGIC);

spin_lock(&ap->ap_lock);
mutex_lock(&ap->ap_lock);
op = ap->ap_op;
wake_up(&ap->ap_waitq);
spin_unlock(&ap->ap_lock);
mutex_unlock(&ap->ap_lock);

splat_vprint(ap->ap_file, SPLAT_ATOMIC_TEST1_NAME,
"Thread %d successfully started: %lu/%lu\n", op,
Expand Down Expand Up @@ -142,28 +142,28 @@ splat_atomic_test1(struct file *file, void *arg)

ap.ap_magic = SPLAT_ATOMIC_TEST_MAGIC;
ap.ap_file = file;
spin_lock_init(&ap.ap_lock);
mutex_init(&ap.ap_lock);
init_waitqueue_head(&ap.ap_waitq);
ap.ap_atomic = SPLAT_ATOMIC_INIT_VALUE;
ap.ap_atomic_exited = 0;

for (i = 0; i < SPLAT_ATOMIC_COUNT_64; i++) {
spin_lock(&ap.ap_lock);
mutex_lock(&ap.ap_lock);
ap.ap_op = i;

thr = (kthread_t *)thread_create(NULL, 0, splat_atomic_work,
&ap, 0, &p0, TS_RUN,
minclsyspri);
if (thr == NULL) {
rc = -ESRCH;
spin_unlock(&ap.ap_lock);
mutex_unlock(&ap.ap_lock);
break;
}

/* Prepare to wait, the new thread will wake us once it
* has made a copy of the unique private passed data */
prepare_to_wait(&ap.ap_waitq, &wait, TASK_UNINTERRUPTIBLE);
spin_unlock(&ap.ap_lock);
mutex_unlock(&ap.ap_lock);
schedule();
}

Expand Down

0 comments on commit b8296bf

Please sign in to comment.