use spinlocks in MCS rwlock

This commit is contained in:
Balazs Gerofi
2017-06-08 14:16:29 +09:00
parent 1ca16b9693
commit 5758dba7cf
3 changed files with 49 additions and 2 deletions

View File

@@ -208,6 +208,8 @@ static void mcs_lock_unlock(struct mcs_lock_node *lock,
} }
#define SPINLOCK_IN_MCS_RWLOCK
// reader/writer lock // reader/writer lock
typedef struct mcs_rwlock_node { typedef struct mcs_rwlock_node {
ihk_atomic_t count; // num of readers (use only common reader) ihk_atomic_t count; // num of readers (use only common reader)
@@ -224,21 +226,31 @@ typedef struct mcs_rwlock_node {
} __attribute__((aligned(64))) mcs_rwlock_node_t; } __attribute__((aligned(64))) mcs_rwlock_node_t;
typedef struct mcs_rwlock_node_irqsave { typedef struct mcs_rwlock_node_irqsave {
#ifndef SPINLOCK_IN_MCS_RWLOCK
struct mcs_rwlock_node node; struct mcs_rwlock_node node;
#endif
unsigned long irqsave; unsigned long irqsave;
} __attribute__((aligned(64))) mcs_rwlock_node_irqsave_t; } __attribute__((aligned(64))) mcs_rwlock_node_irqsave_t;
typedef struct mcs_rwlock_lock { typedef struct mcs_rwlock_lock {
#ifdef SPINLOCK_IN_MCS_RWLOCK
ihk_spinlock_t slock;
#else
struct mcs_rwlock_node reader; /* common reader lock */ struct mcs_rwlock_node reader; /* common reader lock */
struct mcs_rwlock_node *node; /* base */ struct mcs_rwlock_node *node; /* base */
#endif
} __attribute__((aligned(64))) mcs_rwlock_lock_t; } __attribute__((aligned(64))) mcs_rwlock_lock_t;
static void static void
mcs_rwlock_init(struct mcs_rwlock_lock *lock) mcs_rwlock_init(struct mcs_rwlock_lock *lock)
{ {
#ifdef SPINLOCK_IN_MCS_RWLOCK
ihk_mc_spinlock_init(&lock->slock);
#else
ihk_atomic_set(&lock->reader.count, 0); ihk_atomic_set(&lock->reader.count, 0);
lock->reader.type = MCS_RWLOCK_TYPE_COMMON_READER; lock->reader.type = MCS_RWLOCK_TYPE_COMMON_READER;
lock->node = NULL; lock->node = NULL;
#endif
} }
#ifdef DEBUG_MCS_RWLOCK #ifdef DEBUG_MCS_RWLOCK
@@ -253,6 +265,9 @@ __kprintf("[%d] ret mcs_rwlock_writer_lock_noirq\n", ihk_mc_get_processor_id());
static void static void
__mcs_rwlock_writer_lock_noirq(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node *node) __mcs_rwlock_writer_lock_noirq(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node *node)
{ {
#ifdef SPINLOCK_IN_MCS_RWLOCK
ihk_mc_spinlock_lock_noirq(&lock->slock);
#else
struct mcs_rwlock_node *pred; struct mcs_rwlock_node *pred;
preempt_disable(); preempt_disable();
@@ -270,8 +285,10 @@ __mcs_rwlock_writer_lock_noirq(struct mcs_rwlock_lock *lock, struct mcs_rwlock_n
cpu_pause(); cpu_pause();
} }
} }
#endif
} }
#ifndef SPINLOCK_IN_MCS_RWLOCK
static void static void
mcs_rwlock_unlock_readers(struct mcs_rwlock_lock *lock) mcs_rwlock_unlock_readers(struct mcs_rwlock_lock *lock)
{ {
@@ -328,6 +345,7 @@ mcs_rwlock_unlock_readers(struct mcs_rwlock_lock *lock)
f->locked = MCS_RWLOCK_UNLOCKED; f->locked = MCS_RWLOCK_UNLOCKED;
} }
#endif
#ifdef DEBUG_MCS_RWLOCK #ifdef DEBUG_MCS_RWLOCK
#define mcs_rwlock_writer_unlock_noirq(l, n) { \ #define mcs_rwlock_writer_unlock_noirq(l, n) { \
@@ -341,6 +359,9 @@ __kprintf("[%d] ret mcs_rwlock_writer_unlock_noirq\n", ihk_mc_get_processor_id()
static void static void
__mcs_rwlock_writer_unlock_noirq(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node *node) __mcs_rwlock_writer_unlock_noirq(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node *node)
{ {
#ifdef SPINLOCK_IN_MCS_RWLOCK
ihk_mc_spinlock_unlock_noirq(&lock->slock);
#else
if (node->next == NULL) { if (node->next == NULL) {
struct mcs_rwlock_node *old = (struct mcs_rwlock_node *) struct mcs_rwlock_node *old = (struct mcs_rwlock_node *)
atomic_cmpxchg8((unsigned long *)&lock->node, atomic_cmpxchg8((unsigned long *)&lock->node,
@@ -365,6 +386,7 @@ __mcs_rwlock_writer_unlock_noirq(struct mcs_rwlock_lock *lock, struct mcs_rwlock
out: out:
preempt_enable(); preempt_enable();
#endif
} }
#ifdef DEBUG_MCS_RWLOCK #ifdef DEBUG_MCS_RWLOCK
@@ -397,6 +419,9 @@ atomic_inc_ifnot0(ihk_atomic_t *v)
static void static void
__mcs_rwlock_reader_lock_noirq(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node *node) __mcs_rwlock_reader_lock_noirq(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node *node)
{ {
#ifdef SPINLOCK_IN_MCS_RWLOCK
ihk_mc_spinlock_lock_noirq(&lock->slock);
#else
struct mcs_rwlock_node *pred; struct mcs_rwlock_node *pred;
preempt_disable(); preempt_disable();
@@ -445,6 +470,7 @@ __mcs_rwlock_reader_lock_noirq(struct mcs_rwlock_lock *lock, struct mcs_rwlock_n
} }
out: out:
return; return;
#endif
} }
#ifdef DEBUG_MCS_RWLOCK #ifdef DEBUG_MCS_RWLOCK
@@ -459,6 +485,9 @@ __kprintf("[%d] ret mcs_rwlock_reader_unlock_noirq\n", ihk_mc_get_processor_id()
static void static void
__mcs_rwlock_reader_unlock_noirq(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node *node) __mcs_rwlock_reader_unlock_noirq(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node *node)
{ {
#ifdef SPINLOCK_IN_MCS_RWLOCK
ihk_mc_spinlock_unlock_noirq(&lock->slock);
#else
if(ihk_atomic_dec_return(&lock->reader.count)) if(ihk_atomic_dec_return(&lock->reader.count))
goto out; goto out;
@@ -488,6 +517,7 @@ __mcs_rwlock_reader_unlock_noirq(struct mcs_rwlock_lock *lock, struct mcs_rwlock
out: out:
preempt_enable(); preempt_enable();
#endif
} }
#ifdef DEBUG_MCS_RWLOCK #ifdef DEBUG_MCS_RWLOCK
@@ -502,8 +532,12 @@ __kprintf("[%d] ret mcs_rwlock_writer_lock\n", ihk_mc_get_processor_id()); \
static void static void
__mcs_rwlock_writer_lock(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node_irqsave *node) __mcs_rwlock_writer_lock(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node_irqsave *node)
{ {
#ifdef SPINLOCK_IN_MCS_RWLOCK
node->irqsave = ihk_mc_spinlock_lock(&lock->slock);
#else
node->irqsave = cpu_disable_interrupt_save(); node->irqsave = cpu_disable_interrupt_save();
__mcs_rwlock_writer_lock_noirq(lock, &node->node); __mcs_rwlock_writer_lock_noirq(lock, &node->node);
#endif
} }
#ifdef DEBUG_MCS_RWLOCK #ifdef DEBUG_MCS_RWLOCK
@@ -518,8 +552,12 @@ __kprintf("[%d] ret mcs_rwlock_writer_unlock\n", ihk_mc_get_processor_id()); \
static void static void
__mcs_rwlock_writer_unlock(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node_irqsave *node) __mcs_rwlock_writer_unlock(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node_irqsave *node)
{ {
#ifdef SPINLOCK_IN_MCS_RWLOCK
ihk_mc_spinlock_unlock(&lock->slock, node->irqsave);
#else
__mcs_rwlock_writer_unlock_noirq(lock, &node->node); __mcs_rwlock_writer_unlock_noirq(lock, &node->node);
cpu_restore_interrupt(node->irqsave); cpu_restore_interrupt(node->irqsave);
#endif
} }
#ifdef DEBUG_MCS_RWLOCK #ifdef DEBUG_MCS_RWLOCK
@@ -534,8 +572,12 @@ __kprintf("[%d] ret mcs_rwlock_reader_lock\n", ihk_mc_get_processor_id()); \
static void static void
__mcs_rwlock_reader_lock(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node_irqsave *node) __mcs_rwlock_reader_lock(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node_irqsave *node)
{ {
#ifdef SPINLOCK_IN_MCS_RWLOCK
node->irqsave = ihk_mc_spinlock_lock(&lock->slock);
#else
node->irqsave = cpu_disable_interrupt_save(); node->irqsave = cpu_disable_interrupt_save();
__mcs_rwlock_reader_lock_noirq(lock, &node->node); __mcs_rwlock_reader_lock_noirq(lock, &node->node);
#endif
} }
#ifdef DEBUG_MCS_RWLOCK #ifdef DEBUG_MCS_RWLOCK
@@ -550,8 +592,12 @@ __kprintf("[%d] ret mcs_rwlock_reader_unlock\n", ihk_mc_get_processor_id()); \
static void static void
__mcs_rwlock_reader_unlock(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node_irqsave *node) __mcs_rwlock_reader_unlock(struct mcs_rwlock_lock *lock, struct mcs_rwlock_node_irqsave *node)
{ {
#ifdef SPINLOCK_IN_MCS_RWLOCK
ihk_mc_spinlock_unlock(&lock->slock, node->irqsave);
#else
__mcs_rwlock_reader_unlock_noirq(lock, &node->node); __mcs_rwlock_reader_unlock_noirq(lock, &node->node);
cpu_restore_interrupt(node->irqsave); cpu_restore_interrupt(node->irqsave);
#endif
} }
#endif #endif

View File

@@ -29,8 +29,7 @@
#define dkprintf(...) do { if (0) kprintf(__VA_ARGS__); } while (0) #define dkprintf(...) do { if (0) kprintf(__VA_ARGS__); } while (0)
#define ekprintf(...) kprintf(__VA_ARGS__) #define ekprintf(...) kprintf(__VA_ARGS__)
mcs_rwlock_lock_t fileobj_list_lock = mcs_rwlock_lock_t fileobj_list_lock;
{{{0}, MCS_RWLOCK_TYPE_COMMON_READER, 0, 0, 0, NULL}, NULL};
static LIST_HEAD(fileobj_list); static LIST_HEAD(fileobj_list);
#define FILEOBJ_PAGE_HASH_SHIFT 9 #define FILEOBJ_PAGE_HASH_SHIFT 9

View File

@@ -3224,6 +3224,7 @@ process_unlock(struct process *proc, struct mcs_rwlock_node_irqsave *lock)
void void
debug_log(unsigned long arg) debug_log(unsigned long arg)
{ {
#if 0
struct process *p; struct process *p;
struct thread *t; struct thread *t;
int i; int i;
@@ -3276,4 +3277,5 @@ debug_log(unsigned long arg)
} }
break; break;
} }
#endif
} }