From ba3f616d900d1a8caad96d0fb8c4f168c30a8afd Mon Sep 17 00:00:00 2001 From: Bryan Ward Date: Fri, 10 Aug 2012 16:27:47 -0400 Subject: Allow one litmus_lock to control multiple fdsos. Each fdso in a resource group now points to a single litmus_lock object which will arbitrate access to each of the fdsos. --- arch/arm/kernel/calls.S | 1 - arch/x86/kernel/syscall_table_32.S | 1 - include/litmus/fdso.h | 2 +- include/litmus/locking.h | 27 +++------ include/litmus/unistd_32.h | 3 +- include/litmus/unistd_64.h | 4 +- litmus/fdso.c | 4 +- litmus/locking.c | 57 +++++++++++-------- litmus/sched_psn_edf.c | 110 +++++++++++++++++++++++++++++++------ 9 files changed, 139 insertions(+), 70 deletions(-) diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 3444f32562ea..6a4f83eeb6bf 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -399,7 +399,6 @@ CALL(sys_null_call) CALL(sys_dynamic_group_lock) CALL(sys_dynamic_group_unlock) - CALL(sys_dynamic_group_add) #ifndef syscalls_counted .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls #define syscalls_counted diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S index 47028d2ff1ac..652137f34dc5 100644 --- a/arch/x86/kernel/syscall_table_32.S +++ b/arch/x86/kernel/syscall_table_32.S @@ -360,4 +360,3 @@ ENTRY(sys_call_table) .long sys_null_call .long sys_dynamic_group_lock .long sys_dynamic_group_unlock - .long sys_dynamic_group_add diff --git a/include/litmus/fdso.h b/include/litmus/fdso.h index 82f88221f4f0..85a649e2722d 100644 --- a/include/litmus/fdso.h +++ b/include/litmus/fdso.h @@ -73,7 +73,7 @@ static inline void* od_lookup(int od, obj_type_t type) return e && e->obj->type == type ? e->obj->obj : NULL; } -#define lookup_fmlp_sem(od)((struct pi_semaphore*) od_lookup(od, FMLP_SEM)) +#define lookup_fmlp_sem(od)((struct fmlp_semaphore*) od_lookup(od, FMLP_SEM)) #define lookup_srp_sem(od) ((struct srp_semaphore*) od_lookup(od, SRP_SEM)) #define lookup_ics(od) ((struct ics*) od_lookup(od, ICS_ID)) diff --git a/include/litmus/locking.h b/include/litmus/locking.h index e9998946e7de..203466933f3c 100644 --- a/include/litmus/locking.h +++ b/include/litmus/locking.h @@ -1,9 +1,9 @@ #ifndef LITMUS_LOCKING_H #define LITMUS_LOCKING_H -struct litmus_lock_ops; +#include -struct dynamic_group_lock_ops; +struct litmus_lock_ops; /* Generic base struct for LITMUS^RT userspace semaphores. * This structure should be embedded in protocol-specific semaphores. @@ -18,29 +18,20 @@ struct litmus_lock_ops { * Optional methods, allowed by default. */ int (*open)(struct litmus_lock*, void* __user); int (*close)(struct litmus_lock*); + + /* add or remove a resource from control by the dynamic group lock */ + int (*add)(struct litmus_lock*, int); + int (*remove)(struct litmus_lock*, int); /* Current tries to lock/unlock this lock (mandatory methods). */ int (*lock)(struct litmus_lock*); int (*unlock)(struct litmus_lock*); + int (*dynamic_group_lock)(struct litmus_lock*, resource_mask_t); + int (*dynamic_group_unlock)(struct litmus_lock*, resource_mask_t); + /* The lock is no longer being referenced (mandatory method). */ void (*deallocate)(struct litmus_lock*); }; -struct dynamic_group_lock { - struct dynamic_group_lock_ops *ops; - - /* Probably useful for different RNLP variants. */ - int type; -}; - -struct dynamic_group_lock_ops { - // Do we need open and close? - - int (*lock)(struct dynamic_group_lock*); - int (*unlock)(struct dynamic_group_lock*); - - void (*deallocate)(struct dynamic_group_lock*); -}; - #endif diff --git a/include/litmus/unistd_32.h b/include/litmus/unistd_32.h index 1c59c92547c5..04e453e89914 100644 --- a/include/litmus/unistd_32.h +++ b/include/litmus/unistd_32.h @@ -19,6 +19,5 @@ #define __NR_null_call __LSC(11) #define __NR_dynamic_group_lock __LSC(12) #define __NR_dynamic_group_unlock __LSC(13) -#define __NR_dynamic_group_add __LSC(14) -#define NR_litmus_syscalls 15 +#define NR_litmus_syscalls 14 diff --git a/include/litmus/unistd_64.h b/include/litmus/unistd_64.h index 1ad4aa92ae5f..ae55b4884666 100644 --- a/include/litmus/unistd_64.h +++ b/include/litmus/unistd_64.h @@ -33,7 +33,5 @@ __SYSCALL(__NR_null_call, sys_null_call) __SYSCALL(__NR_dynamic_group_lock, sys_dynamic_group_lock) #define __NR_dynamic_group_unlock __LSC(13) __SYSCALL(__NR_dynamic_group_unlock, sys_dynamic_group_unlock) -#define __NR_dynamic_group_add __LSC(14) -__SYSCALL(__NR_dynamic_group_add, sys_dynamic_group_add) -#define NR_litmus_syscalls 15 +#define NR_litmus_syscalls 14 diff --git a/litmus/fdso.c b/litmus/fdso.c index fdd9a6e805c7..41852d7b14d2 100644 --- a/litmus/fdso.c +++ b/litmus/fdso.c @@ -27,7 +27,7 @@ static const struct fdso_ops* fdso_ops[] = { &generic_lock_ops, /* MPCP_VS_SEM */ &generic_lock_ops, /* DPCP_SEM */ &generic_lock_ops, /* PCP_SEM */ - &generic_lock_ops, /* RNLP_SEM */ + &generic_lock_ops, /* DGL_SEM */ }; static int fdso_create(void** obj_ref, obj_type_t type, void* __user config) @@ -141,7 +141,7 @@ static void put_inode_obj(struct inode_obj_id* obj) } } -static struct od_table_entry* get_od_entry(struct task_struct* t) +static struct od_table_entry* get_od_entry(struct task_struct* t) { struct od_table_entry* table; int i; diff --git a/litmus/locking.c b/litmus/locking.c index e0e6c1dc6256..348a4be97cf9 100644 --- a/litmus/locking.c +++ b/litmus/locking.c @@ -68,7 +68,7 @@ static void destroy_generic_lock(obj_type_t type, void* obj) lock->ops->deallocate(lock); } -bool check_mask_valid(resource_mask_t mask) +bool check_mask_valid(struct litmus_lock* l, resource_mask_t mask) { // this should really check if all of the resources requested are // controlled by the dynamic group lock. this can be done with bitwise @@ -76,35 +76,48 @@ bool check_mask_valid(resource_mask_t mask) return true; } -asmlinkage long sys_dynamic_group_lock(int mask) +asmlinkage long sys_dynamic_group_lock(resource_mask_t lock_ods) { - //long err = -EINVAL; + long err = -EINVAL; + struct od_table_entry* entry; + struct litmus_lock* l; - //TS_LOCK_START; + TS_LOCK_START; - //TS_LOCK_END; + entry = get_entry_for_od(ffs(lock_ods)-1); + if (entry && is_lock(entry)) { + l = get_lock(entry); + if (check_mask_valid(l, mask)){ + TRACE_CUR("attempts to lock %d\n", lock_ods); + err = l->ops->dynamic_group_lock(l, lock_ods); + } + } - //return err; + TS_LOCK_END; - TRACE("Successfully called the dynamic group lock system call"); - printk(KERN_INFO "printk: Successfully called the dynamic group lock system call"); - return -EINVAL; + return err; } asmlinkage long sys_dynamic_group_unlock(resource_mask_t lock_ods) { - return 0; -} + long err = -EINVAL; + struct od_table_entry* entry; + struct litmus_lock* l; -/* - * Point the new_od to the existing dynamic_group_lock pointed to in the entry - * for dgl_od. In so doing, update the metadata for the dgl so the masks are - * correct. - */ -asmlinkage long sys_dynamic_group_add(int dgl_od, int new_od) -{ -// long err = -EINVAL; - return 0; + TS_UNLOCK_START; + + entry = get_entry_for_od(ffs(lock_ods)-1); + if (entry && is_lock(entry)) { + l = get_lock(entry); + if (check_mask_valid(l, mask)){ + TRACE_CUR("attempts to unlock all resources in 0x%p\n",l); + err = l->ops->dynamic_group_unlock(l, lock_ods); + } + } + + TS_UNLOCK_END; + + return err; } asmlinkage long sys_litmus_lock(int lock_od) @@ -113,10 +126,6 @@ asmlinkage long sys_litmus_lock(int lock_od) struct od_table_entry* entry; struct litmus_lock* l; - TS_SYSCALL_IN_START; - - TS_SYSCALL_IN_END; - TS_LOCK_START; entry = get_entry_for_od(lock_od); diff --git a/litmus/sched_psn_edf.c b/litmus/sched_psn_edf.c index ce97b73829bf..7d81f8a245a1 100644 --- a/litmus/sched_psn_edf.c +++ b/litmus/sched_psn_edf.c @@ -22,6 +22,7 @@ #include #include #include +#include typedef struct { rt_domain_t domain; @@ -406,7 +407,7 @@ struct fmlp_semaphore { }; struct dgl_semaphore { - struct dynamic_group_lock dynamic_group_lock; + struct litmus_lock litmus_lock; /* bitmask of resources that are currently locked. */ resource_mask_t locked; @@ -431,9 +432,9 @@ static inline struct fmlp_semaphore* fmlp_from_lock(struct litmus_lock* lock) return container_of(lock, struct fmlp_semaphore, litmus_lock); } -static inline struct dgl_semaphore* dgl_from_lock(struct dynamic_group_lock* dgl) +static inline struct dgl_semaphore* dgl_from_lock(struct litmus_lock* lock) { - return container_of(dgl, struct dgl_semaphore, dynamic_group_lock); + return container_of(lock, struct dgl_semaphore, litmus_lock); } int psnedf_fmlp_lock(struct litmus_lock* l) @@ -561,11 +562,6 @@ void psnedf_fmlp_free(struct litmus_lock* lock) kfree(fmlp_from_lock(lock)); } -void psnedf_dgl_free(struct dynamic_group_lock* dgl) -{ - kfree(dgl_from_lock(dgl)); -} - static struct litmus_lock_ops psnedf_fmlp_lock_ops = { .close = psnedf_fmlp_close, .lock = psnedf_fmlp_lock, @@ -573,11 +569,62 @@ static struct litmus_lock_ops psnedf_fmlp_lock_ops = { .deallocate = psnedf_fmlp_free, }; -//static struct dynamic_group_lock_ops psnedf_dgl_lock_ops = { -// .lock = psnedf_dgl_lock, -// .unlock = psnedf_dgl_unlock, -// .deallocate = psnedf_dgl_free, -//} +int psnedf_dgl_close(struct litmus_lock* l) +{ + return 0; +} + +int psnedf_dgl_add(struct litmus_lock* l, int od) +{ + return 0; +} + +int psnedf_dgl_remove(struct litmus_lock* l, int od) +{ + return 0; +} + +int psnedf_dgl_lock(struct litmus_lock* l) +{ + return 0; +} + +int psnedf_dgl_unlock(struct litmus_lock* l) +{ + return 0; +} + +int psnedf_dgl_dynamic_group_lock(struct litmus_lock* l, resource_mask_t lock_ods) +{ + struct task_struct* t = current; + struct dgl_semaphore *sem = dgl_from_lock(l); + TRACE("Trying to lock a DGL\n"); + return 0; +} + +int psnedf_dgl_dynamic_group_unlock(struct litmus_lock* l, resource_mask_t lock_ods) +{ + TRACE("Trying to unlock a DGL\n"); + return 0; +} + +void psnedf_dgl_free(struct litmus_lock* l) +{ + //if (l) + // kfree(dgl_from_lock(l)); + TRACE("I'll free things later!\n"); +} + +static struct litmus_lock_ops psnedf_dgl_lock_ops = { + .close = psnedf_dgl_close, + .add = psnedf_dgl_add, + .remove = psnedf_dgl_remove, + .lock = psnedf_dgl_lock, + .unlock = psnedf_dgl_unlock, + .dynamic_group_lock = psnedf_dgl_dynamic_group_lock, + .dynamic_group_unlock = psnedf_dgl_dynamic_group_unlock, + .deallocate = psnedf_dgl_free, +}; static struct litmus_lock* psnedf_new_fmlp(void) { @@ -594,7 +641,7 @@ static struct litmus_lock* psnedf_new_fmlp(void) return &sem->litmus_lock; } -static struct dynamic_group_lock* psnedf_new_dgl(void) +static struct litmus_lock* psnedf_new_dgl(void) { struct dgl_semaphore* sem; @@ -605,18 +652,19 @@ static struct dynamic_group_lock* psnedf_new_dgl(void) sem->resource_holders = 0; sem->dgl_resources = 0; init_waitqueue_head(&sem->wait); - //sem->dynamic_group_lock.ops = &psnedf_dgl_lock_ops; - return &sem->dynamic_group_lock; + sem->litmus_lock.ops = &psnedf_dgl_lock_ops; + return &sem->litmus_lock; } /* **** lock constructor **** */ static long psnedf_allocate_lock(struct litmus_lock **lock, int type, - void* __user unused) + void* __user config) { int err = -ENXIO; struct srp_semaphore* srp; + struct od_table_entry* entry; /* PSN-EDF currently supports the SRP for local resources and the FMLP * for global resources. */ @@ -639,6 +687,33 @@ static long psnedf_allocate_lock(struct litmus_lock **lock, int type, } else err = -ENOMEM; break; + + case DGL_SEM: + /* assume that config is an int, and that config < 0 means create a new DGL + * and that a config > 0 means point this resource to the existing DGL + * for the resource in entry number config. + */ + TRACE("config: %d\n", *(int*)(config)); + if (*(int*)(config) < 0){ + *lock = psnedf_new_dgl(); + if (*lock) + err = 0; + else + err = -ENOMEM; + /* In this case, we are adding a resource to an existing lock */ + } else { + entry = get_entry_for_od(*(int*)(config)); + if (entry && entry->obj && entry->obj->type == DGL_SEM){ + *lock = (struct litmus_lock*) entry->obj->obj; + err = 0; + } else { + err = -EINVAL; + printk(KERN_DEBUG "Cannot add to that group!\n"); + while(1); + } + } + + break; }; return err; @@ -646,7 +721,6 @@ static long psnedf_allocate_lock(struct litmus_lock **lock, int type, #endif - static long psnedf_activate_plugin(void) { #ifdef CONFIG_RELEASE_MASTER -- cgit v1.2.2