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

Commit

Permalink
Merge branch 'splat'
Browse files Browse the repository at this point in the history
Additional debugging, some cleanup, and an assortment of fixes
to the SPLAT tests and infrastructure.  Full details in the
individual patches.

Signed-off-by: Brian Behlendorf <[email protected]>
  • Loading branch information
behlendorf committed Nov 6, 2012
2 parents 87efc30 + 1112486 commit 65c2fc5
Show file tree
Hide file tree
Showing 22 changed files with 93 additions and 81 deletions.
3 changes: 2 additions & 1 deletion include/sys/condvar.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@
* calling any of the wait/signal funs, and passed into the wait funs.
*/
#define CV_MAGIC 0x346545f4
#define CV_POISON 0x95
#define CV_DESTROY 0x346545f5

typedef struct {
int cv_magic;
wait_queue_head_t cv_event;
wait_queue_head_t cv_destroy;
atomic_t cv_refs;
atomic_t cv_waiters;
kmutex_t *cv_mutex;
} kcondvar_t;
Expand Down
1 change: 0 additions & 1 deletion include/sys/kmem.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mm_compat.h>
#include <linux/spinlock.h>
#include <linux/rwsem.h>
#include <linux/hash.h>
Expand Down
2 changes: 2 additions & 0 deletions include/sys/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
#include <linux/proc_compat.h>
#include <linux/math64_compat.h>
#include <linux/zlib_compat.h>
#include <linux/mm_compat.h>
#include <linux/delay.h>

#ifndef HAVE_UINTPTR_T
typedef unsigned long uintptr_t;
Expand Down
32 changes: 24 additions & 8 deletions module/spl/spl-condvar.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ __cv_init(kcondvar_t *cvp, char *name, kcv_type_t type, void *arg)
init_waitqueue_head(&cvp->cv_event);
init_waitqueue_head(&cvp->cv_destroy);
atomic_set(&cvp->cv_waiters, 0);
atomic_set(&cvp->cv_refs, 1);
cvp->cv_mutex = NULL;

/* We may be called when there is a non-zero preempt_count or
Expand All @@ -63,12 +64,13 @@ EXPORT_SYMBOL(__cv_init);
static int
cv_destroy_wakeup(kcondvar_t *cvp)
{
if ((cvp->cv_mutex != NULL) ||
(waitqueue_active(&cvp->cv_event)) ||
(atomic_read(&cvp->cv_waiters) > 0))
return 0;
if (!atomic_read(&cvp->cv_waiters) && !atomic_read(&cvp->cv_refs)) {
ASSERT(cvp->cv_mutex == NULL);
ASSERT(!waitqueue_active(&cvp->cv_event));
return 1;
}

return 1;
return 0;
}

void
Expand All @@ -78,11 +80,15 @@ __cv_destroy(kcondvar_t *cvp)
ASSERT(cvp);
ASSERT(cvp->cv_magic == CV_MAGIC);

/* Block until all waiters have woken */
cvp->cv_magic = CV_DESTROY;
atomic_dec(&cvp->cv_refs);

/* Block until all waiters are woken and references dropped. */
while (cv_destroy_wakeup(cvp) == 0)
wait_event_timeout(cvp->cv_destroy, cv_destroy_wakeup(cvp), 1);

ASSERT3P(cvp->cv_mutex, ==, NULL);
ASSERT3S(atomic_read(&cvp->cv_refs), ==, 0);
ASSERT3S(atomic_read(&cvp->cv_waiters), ==, 0);
ASSERT3S(waitqueue_active(&cvp->cv_event), ==, 0);

Expand All @@ -100,6 +106,7 @@ cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state)
ASSERT(mp);
ASSERT(cvp->cv_magic == CV_MAGIC);
ASSERT(mutex_owned(mp));
atomic_inc(&cvp->cv_refs);

if (cvp->cv_mutex == NULL)
cvp->cv_mutex = mp;
Expand All @@ -124,6 +131,7 @@ cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state)
}

finish_wait(&cvp->cv_event, &wait);
atomic_dec(&cvp->cv_refs);

SEXIT;
}
Expand Down Expand Up @@ -157,6 +165,7 @@ __cv_timedwait_common(kcondvar_t *cvp, kmutex_t *mp,
ASSERT(mp);
ASSERT(cvp->cv_magic == CV_MAGIC);
ASSERT(mutex_owned(mp));
atomic_inc(&cvp->cv_refs);

if (cvp->cv_mutex == NULL)
cvp->cv_mutex = mp;
Expand All @@ -166,8 +175,10 @@ __cv_timedwait_common(kcondvar_t *cvp, kmutex_t *mp,

/* XXX - Does not handle jiffie wrap properly */
time_left = expire_time - jiffies;
if (time_left <= 0)
if (time_left <= 0) {
atomic_dec(&cvp->cv_refs);
SRETURN(-1);
}

prepare_to_wait_exclusive(&cvp->cv_event, &wait, state);
atomic_inc(&cvp->cv_waiters);
Expand All @@ -186,6 +197,7 @@ __cv_timedwait_common(kcondvar_t *cvp, kmutex_t *mp,
}

finish_wait(&cvp->cv_event, &wait);
atomic_dec(&cvp->cv_refs);

SRETURN(time_left > 0 ? time_left : -1);
}
Expand All @@ -210,6 +222,7 @@ __cv_signal(kcondvar_t *cvp)
SENTRY;
ASSERT(cvp);
ASSERT(cvp->cv_magic == CV_MAGIC);
atomic_inc(&cvp->cv_refs);

/* All waiters are added with WQ_FLAG_EXCLUSIVE so only one
* waiter will be set runable with each call to wake_up().
Expand All @@ -218,22 +231,25 @@ __cv_signal(kcondvar_t *cvp)
if (atomic_read(&cvp->cv_waiters) > 0)
wake_up(&cvp->cv_event);

atomic_dec(&cvp->cv_refs);
SEXIT;
}
EXPORT_SYMBOL(__cv_signal);

void
__cv_broadcast(kcondvar_t *cvp)
{
SENTRY;
ASSERT(cvp);
ASSERT(cvp->cv_magic == CV_MAGIC);
SENTRY;
atomic_inc(&cvp->cv_refs);

/* Wake_up_all() will wake up all waiters even those which
* have the WQ_FLAG_EXCLUSIVE flag set. */
if (atomic_read(&cvp->cv_waiters) > 0)
wake_up_all(&cvp->cv_event);

atomic_dec(&cvp->cv_refs);
SEXIT;
}
EXPORT_SYMBOL(__cv_broadcast);
16 changes: 9 additions & 7 deletions module/splat/splat-atomic.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
* Solaris Porting LAyer Tests (SPLAT) Atomic Tests.
\*****************************************************************************/

#include <sys/atomic.h>
#include <sys/thread.h>
#include "splat-internal.h"

#define SPLAT_ATOMIC_NAME "atomic"
Expand All @@ -49,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 @@ -67,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 @@ -140,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
1 change: 1 addition & 0 deletions module/splat/splat-condvar.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* Solaris Porting LAyer Tests (SPLAT) Condition Variable Tests.
\*****************************************************************************/

#include <sys/condvar.h>
#include "splat-internal.h"

#define SPLAT_CONDVAR_NAME "condvar"
Expand Down
1 change: 1 addition & 0 deletions module/splat/splat-cred.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* Solaris Porting LAyer Tests (SPLAT) Credential Tests.
\*****************************************************************************/

#include <sys/cred.h>
#include "splat-internal.h"

#define SPLAT_CRED_NAME "cred"
Expand Down
31 changes: 20 additions & 11 deletions module/splat/splat-ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@
* of regression tests or particular tests.
\*****************************************************************************/

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <sys/types.h>
#include <sys/debug.h>
#include "splat-internal.h"

static spl_class *splat_class;
Expand All @@ -63,7 +71,7 @@ splat_open(struct inode *inode, struct file *file)
if (info == NULL)
return -ENOMEM;

spin_lock_init(&info->info_lock);
mutex_init(&info->info_lock);
info->info_size = SPLAT_INFO_BUFFER_SIZE;
info->info_buffer = (char *)vmalloc(SPLAT_INFO_BUFFER_SIZE);
if (info->info_buffer == NULL) {
Expand Down Expand Up @@ -92,6 +100,7 @@ splat_release(struct inode *inode, struct file *file)
ASSERT(info);
ASSERT(info->info_buffer);

mutex_destroy(&info->info_lock);
vfree(info->info_buffer);
kfree(info);

Expand All @@ -106,10 +115,10 @@ splat_buffer_clear(struct file *file, splat_cfg_t *kcfg, unsigned long arg)
ASSERT(info);
ASSERT(info->info_buffer);

spin_lock(&info->info_lock);
mutex_lock(&info->info_lock);
memset(info->info_buffer, 0, info->info_size);
info->info_head = info->info_buffer;
spin_unlock(&info->info_lock);
mutex_unlock(&info->info_lock);

return 0;
}
Expand All @@ -124,7 +133,7 @@ splat_buffer_size(struct file *file, splat_cfg_t *kcfg, unsigned long arg)
ASSERT(info);
ASSERT(info->info_buffer);

spin_lock(&info->info_lock);
mutex_lock(&info->info_lock);
if (kcfg->cfg_arg1 > 0) {

size = kcfg->cfg_arg1;
Expand All @@ -149,7 +158,7 @@ splat_buffer_size(struct file *file, splat_cfg_t *kcfg, unsigned long arg)
if (copy_to_user((struct splat_cfg_t __user *)arg, kcfg, sizeof(*kcfg)))
rc = -EFAULT;
out:
spin_unlock(&info->info_lock);
mutex_unlock(&info->info_lock);

return rc;
}
Expand Down Expand Up @@ -500,7 +509,7 @@ static ssize_t splat_write(struct file *file, const char __user *buf,
ASSERT(info);
ASSERT(info->info_buffer);

spin_lock(&info->info_lock);
mutex_lock(&info->info_lock);

/* Write beyond EOF */
if (*ppos >= info->info_size) {
Expand All @@ -520,7 +529,7 @@ static ssize_t splat_write(struct file *file, const char __user *buf,
*ppos += count;
rc = count;
out:
spin_unlock(&info->info_lock);
mutex_unlock(&info->info_lock);
return rc;
}

Expand All @@ -537,7 +546,7 @@ static ssize_t splat_read(struct file *file, char __user *buf,
ASSERT(info);
ASSERT(info->info_buffer);

spin_lock(&info->info_lock);
mutex_lock(&info->info_lock);

/* Read beyond EOF */
if (*ppos >= info->info_size)
Expand All @@ -555,7 +564,7 @@ static ssize_t splat_read(struct file *file, char __user *buf,
*ppos += count;
rc = count;
out:
spin_unlock(&info->info_lock);
mutex_unlock(&info->info_lock);
return rc;
}

Expand All @@ -571,7 +580,7 @@ static loff_t splat_seek(struct file *file, loff_t offset, int origin)
ASSERT(info);
ASSERT(info->info_buffer);

spin_lock(&info->info_lock);
mutex_lock(&info->info_lock);

switch (origin) {
case 0: /* SEEK_SET - No-op just do it */
Expand All @@ -590,7 +599,7 @@ static loff_t splat_seek(struct file *file, loff_t offset, int origin)
rc = offset;
}

spin_unlock(&info->info_lock);
mutex_unlock(&info->info_lock);

return rc;
}
Expand Down
1 change: 1 addition & 0 deletions module/splat/splat-generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* Solaris Porting LAyer Tests (SPLAT) Generic Tests.
\*****************************************************************************/

#include <sys/sunddi.h>
#include "splat-internal.h"

#define SPLAT_GENERIC_NAME "generic"
Expand Down
Loading

0 comments on commit 65c2fc5

Please sign in to comment.