use spinlocks in MCS rwlock
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user