aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan Ward <bcw@cs.unc.edu>2012-08-10 16:27:47 -0400
committerBryan Ward <bcw@cs.unc.edu>2013-04-16 14:34:35 -0400
commitba3f616d900d1a8caad96d0fb8c4f168c30a8afd (patch)
treee227efbddcc7582d3d164d177683aaedb6e8f39d
parentb2d92665e4dadc946f0c84b7eec7b6eae6be0d7f (diff)
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.
-rw-r--r--arch/arm/kernel/calls.S1
-rw-r--r--arch/x86/kernel/syscall_table_32.S1
-rw-r--r--include/litmus/fdso.h2
-rw-r--r--include/litmus/locking.h27
-rw-r--r--include/litmus/unistd_32.h3
-rw-r--r--include/litmus/unistd_64.h4
-rw-r--r--litmus/fdso.c4
-rw-r--r--litmus/locking.c57
-rw-r--r--litmus/sched_psn_edf.c110
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 @@
399 CALL(sys_null_call) 399 CALL(sys_null_call)
400 CALL(sys_dynamic_group_lock) 400 CALL(sys_dynamic_group_lock)
401 CALL(sys_dynamic_group_unlock) 401 CALL(sys_dynamic_group_unlock)
402 CALL(sys_dynamic_group_add)
403#ifndef syscalls_counted 402#ifndef syscalls_counted
404.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls 403.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
405#define syscalls_counted 404#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)
360 .long sys_null_call 360 .long sys_null_call
361 .long sys_dynamic_group_lock 361 .long sys_dynamic_group_lock
362 .long sys_dynamic_group_unlock 362 .long sys_dynamic_group_unlock
363 .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)
73 return e && e->obj->type == type ? e->obj->obj : NULL; 73 return e && e->obj->type == type ? e->obj->obj : NULL;
74} 74}
75 75
76#define lookup_fmlp_sem(od)((struct pi_semaphore*) od_lookup(od, FMLP_SEM)) 76#define lookup_fmlp_sem(od)((struct fmlp_semaphore*) od_lookup(od, FMLP_SEM))
77#define lookup_srp_sem(od) ((struct srp_semaphore*) od_lookup(od, SRP_SEM)) 77#define lookup_srp_sem(od) ((struct srp_semaphore*) od_lookup(od, SRP_SEM))
78#define lookup_ics(od) ((struct ics*) od_lookup(od, ICS_ID)) 78#define lookup_ics(od) ((struct ics*) od_lookup(od, ICS_ID))
79 79
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 @@
1#ifndef LITMUS_LOCKING_H 1#ifndef LITMUS_LOCKING_H
2#define LITMUS_LOCKING_H 2#define LITMUS_LOCKING_H
3 3
4struct litmus_lock_ops; 4#include <litmus/fdso.h>
5 5
6struct dynamic_group_lock_ops; 6struct litmus_lock_ops;
7 7
8/* Generic base struct for LITMUS^RT userspace semaphores. 8/* Generic base struct for LITMUS^RT userspace semaphores.
9 * This structure should be embedded in protocol-specific semaphores. 9 * This structure should be embedded in protocol-specific semaphores.
@@ -18,29 +18,20 @@ struct litmus_lock_ops {
18 * Optional methods, allowed by default. */ 18 * Optional methods, allowed by default. */
19 int (*open)(struct litmus_lock*, void* __user); 19 int (*open)(struct litmus_lock*, void* __user);
20 int (*close)(struct litmus_lock*); 20 int (*close)(struct litmus_lock*);
21
22 /* add or remove a resource from control by the dynamic group lock */
23 int (*add)(struct litmus_lock*, int);
24 int (*remove)(struct litmus_lock*, int);
21 25
22 /* Current tries to lock/unlock this lock (mandatory methods). */ 26 /* Current tries to lock/unlock this lock (mandatory methods). */
23 int (*lock)(struct litmus_lock*); 27 int (*lock)(struct litmus_lock*);
24 int (*unlock)(struct litmus_lock*); 28 int (*unlock)(struct litmus_lock*);
25 29
30 int (*dynamic_group_lock)(struct litmus_lock*, resource_mask_t);
31 int (*dynamic_group_unlock)(struct litmus_lock*, resource_mask_t);
32
26 /* The lock is no longer being referenced (mandatory method). */ 33 /* The lock is no longer being referenced (mandatory method). */
27 void (*deallocate)(struct litmus_lock*); 34 void (*deallocate)(struct litmus_lock*);
28}; 35};
29 36
30struct dynamic_group_lock {
31 struct dynamic_group_lock_ops *ops;
32
33 /* Probably useful for different RNLP variants. */
34 int type;
35};
36
37struct dynamic_group_lock_ops {
38 // Do we need open and close?
39
40 int (*lock)(struct dynamic_group_lock*);
41 int (*unlock)(struct dynamic_group_lock*);
42
43 void (*deallocate)(struct dynamic_group_lock*);
44};
45
46#endif 37#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 @@
19#define __NR_null_call __LSC(11) 19#define __NR_null_call __LSC(11)
20#define __NR_dynamic_group_lock __LSC(12) 20#define __NR_dynamic_group_lock __LSC(12)
21#define __NR_dynamic_group_unlock __LSC(13) 21#define __NR_dynamic_group_unlock __LSC(13)
22#define __NR_dynamic_group_add __LSC(14)
23 22
24#define NR_litmus_syscalls 15 23#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)
33__SYSCALL(__NR_dynamic_group_lock, sys_dynamic_group_lock) 33__SYSCALL(__NR_dynamic_group_lock, sys_dynamic_group_lock)
34#define __NR_dynamic_group_unlock __LSC(13) 34#define __NR_dynamic_group_unlock __LSC(13)
35__SYSCALL(__NR_dynamic_group_unlock, sys_dynamic_group_unlock) 35__SYSCALL(__NR_dynamic_group_unlock, sys_dynamic_group_unlock)
36#define __NR_dynamic_group_add __LSC(14)
37__SYSCALL(__NR_dynamic_group_add, sys_dynamic_group_add)
38 36
39#define NR_litmus_syscalls 15 37#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[] = {
27 &generic_lock_ops, /* MPCP_VS_SEM */ 27 &generic_lock_ops, /* MPCP_VS_SEM */
28 &generic_lock_ops, /* DPCP_SEM */ 28 &generic_lock_ops, /* DPCP_SEM */
29 &generic_lock_ops, /* PCP_SEM */ 29 &generic_lock_ops, /* PCP_SEM */
30 &generic_lock_ops, /* RNLP_SEM */ 30 &generic_lock_ops, /* DGL_SEM */
31}; 31};
32 32
33static int fdso_create(void** obj_ref, obj_type_t type, void* __user config) 33static 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)
141 } 141 }
142} 142}
143 143
144static struct od_table_entry* get_od_entry(struct task_struct* t) 144static struct od_table_entry* get_od_entry(struct task_struct* t)
145{ 145{
146 struct od_table_entry* table; 146 struct od_table_entry* table;
147 int i; 147 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)
68 lock->ops->deallocate(lock); 68 lock->ops->deallocate(lock);
69} 69}
70 70
71bool check_mask_valid(resource_mask_t mask) 71bool check_mask_valid(struct litmus_lock* l, resource_mask_t mask)
72{ 72{
73 // this should really check if all of the resources requested are 73 // this should really check if all of the resources requested are
74 // controlled by the dynamic group lock. this can be done with bitwise 74 // controlled by the dynamic group lock. this can be done with bitwise
@@ -76,35 +76,48 @@ bool check_mask_valid(resource_mask_t mask)
76 return true; 76 return true;
77} 77}
78 78
79asmlinkage long sys_dynamic_group_lock(int mask) 79asmlinkage long sys_dynamic_group_lock(resource_mask_t lock_ods)
80{ 80{
81 //long err = -EINVAL; 81 long err = -EINVAL;
82 struct od_table_entry* entry;
83 struct litmus_lock* l;
82 84
83 //TS_LOCK_START; 85 TS_LOCK_START;
84 86
85 //TS_LOCK_END; 87 entry = get_entry_for_od(ffs(lock_ods)-1);
88 if (entry && is_lock(entry)) {
89 l = get_lock(entry);
90 if (check_mask_valid(l, mask)){
91 TRACE_CUR("attempts to lock %d\n", lock_ods);
92 err = l->ops->dynamic_group_lock(l, lock_ods);
93 }
94 }
86 95
87 //return err; 96 TS_LOCK_END;
88 97
89 TRACE("Successfully called the dynamic group lock system call"); 98 return err;
90 printk(KERN_INFO "printk: Successfully called the dynamic group lock system call");
91 return -EINVAL;
92} 99}
93 100
94asmlinkage long sys_dynamic_group_unlock(resource_mask_t lock_ods) 101asmlinkage long sys_dynamic_group_unlock(resource_mask_t lock_ods)
95{ 102{
96 return 0; 103 long err = -EINVAL;
97} 104 struct od_table_entry* entry;
105 struct litmus_lock* l;
98 106
99/* 107 TS_UNLOCK_START;
100 * Point the new_od to the existing dynamic_group_lock pointed to in the entry 108
101 * for dgl_od. In so doing, update the metadata for the dgl so the masks are 109 entry = get_entry_for_od(ffs(lock_ods)-1);
102 * correct. 110 if (entry && is_lock(entry)) {
103 */ 111 l = get_lock(entry);
104asmlinkage long sys_dynamic_group_add(int dgl_od, int new_od) 112 if (check_mask_valid(l, mask)){
105{ 113 TRACE_CUR("attempts to unlock all resources in 0x%p\n",l);
106// long err = -EINVAL; 114 err = l->ops->dynamic_group_unlock(l, lock_ods);
107 return 0; 115 }
116 }
117
118 TS_UNLOCK_END;
119
120 return err;
108} 121}
109 122
110asmlinkage long sys_litmus_lock(int lock_od) 123asmlinkage long sys_litmus_lock(int lock_od)
@@ -113,10 +126,6 @@ asmlinkage long sys_litmus_lock(int lock_od)
113 struct od_table_entry* entry; 126 struct od_table_entry* entry;
114 struct litmus_lock* l; 127 struct litmus_lock* l;
115 128
116 TS_SYSCALL_IN_START;
117
118 TS_SYSCALL_IN_END;
119
120 TS_LOCK_START; 129 TS_LOCK_START;
121 130
122 entry = get_entry_for_od(lock_od); 131 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 @@
22#include <litmus/edf_common.h> 22#include <litmus/edf_common.h>
23#include <litmus/sched_trace.h> 23#include <litmus/sched_trace.h>
24#include <litmus/trace.h> 24#include <litmus/trace.h>
25#include <litmus/fdso.h>
25 26
26typedef struct { 27typedef struct {
27 rt_domain_t domain; 28 rt_domain_t domain;
@@ -406,7 +407,7 @@ struct fmlp_semaphore {
406}; 407};
407 408
408struct dgl_semaphore { 409struct dgl_semaphore {
409 struct dynamic_group_lock dynamic_group_lock; 410 struct litmus_lock litmus_lock;
410 411
411 /* bitmask of resources that are currently locked. */ 412 /* bitmask of resources that are currently locked. */
412 resource_mask_t locked; 413 resource_mask_t locked;
@@ -431,9 +432,9 @@ static inline struct fmlp_semaphore* fmlp_from_lock(struct litmus_lock* lock)
431 return container_of(lock, struct fmlp_semaphore, litmus_lock); 432 return container_of(lock, struct fmlp_semaphore, litmus_lock);
432} 433}
433 434
434static inline struct dgl_semaphore* dgl_from_lock(struct dynamic_group_lock* dgl) 435static inline struct dgl_semaphore* dgl_from_lock(struct litmus_lock* lock)
435{ 436{
436 return container_of(dgl, struct dgl_semaphore, dynamic_group_lock); 437 return container_of(lock, struct dgl_semaphore, litmus_lock);
437} 438}
438 439
439int psnedf_fmlp_lock(struct litmus_lock* l) 440int psnedf_fmlp_lock(struct litmus_lock* l)
@@ -561,11 +562,6 @@ void psnedf_fmlp_free(struct litmus_lock* lock)
561 kfree(fmlp_from_lock(lock)); 562 kfree(fmlp_from_lock(lock));
562} 563}
563 564
564void psnedf_dgl_free(struct dynamic_group_lock* dgl)
565{
566 kfree(dgl_from_lock(dgl));
567}
568
569static struct litmus_lock_ops psnedf_fmlp_lock_ops = { 565static struct litmus_lock_ops psnedf_fmlp_lock_ops = {
570 .close = psnedf_fmlp_close, 566 .close = psnedf_fmlp_close,
571 .lock = psnedf_fmlp_lock, 567 .lock = psnedf_fmlp_lock,
@@ -573,11 +569,62 @@ static struct litmus_lock_ops psnedf_fmlp_lock_ops = {
573 .deallocate = psnedf_fmlp_free, 569 .deallocate = psnedf_fmlp_free,
574}; 570};
575 571
576//static struct dynamic_group_lock_ops psnedf_dgl_lock_ops = { 572int psnedf_dgl_close(struct litmus_lock* l)
577// .lock = psnedf_dgl_lock, 573{
578// .unlock = psnedf_dgl_unlock, 574 return 0;
579// .deallocate = psnedf_dgl_free, 575}
580//} 576
577int psnedf_dgl_add(struct litmus_lock* l, int od)
578{
579 return 0;
580}
581
582int psnedf_dgl_remove(struct litmus_lock* l, int od)
583{
584 return 0;
585}
586
587int psnedf_dgl_lock(struct litmus_lock* l)
588{
589 return 0;
590}
591
592int psnedf_dgl_unlock(struct litmus_lock* l)
593{
594 return 0;
595}
596
597int psnedf_dgl_dynamic_group_lock(struct litmus_lock* l, resource_mask_t lock_ods)
598{
599 struct task_struct* t = current;
600 struct dgl_semaphore *sem = dgl_from_lock(l);
601 TRACE("Trying to lock a DGL\n");
602 return 0;
603}
604
605int psnedf_dgl_dynamic_group_unlock(struct litmus_lock* l, resource_mask_t lock_ods)
606{
607 TRACE("Trying to unlock a DGL\n");
608 return 0;
609}
610
611void psnedf_dgl_free(struct litmus_lock* l)
612{
613 //if (l)
614 // kfree(dgl_from_lock(l));
615 TRACE("I'll free things later!\n");
616}
617
618static struct litmus_lock_ops psnedf_dgl_lock_ops = {
619 .close = psnedf_dgl_close,
620 .add = psnedf_dgl_add,
621 .remove = psnedf_dgl_remove,
622 .lock = psnedf_dgl_lock,
623 .unlock = psnedf_dgl_unlock,
624 .dynamic_group_lock = psnedf_dgl_dynamic_group_lock,
625 .dynamic_group_unlock = psnedf_dgl_dynamic_group_unlock,
626 .deallocate = psnedf_dgl_free,
627};
581 628
582static struct litmus_lock* psnedf_new_fmlp(void) 629static struct litmus_lock* psnedf_new_fmlp(void)
583{ 630{
@@ -594,7 +641,7 @@ static struct litmus_lock* psnedf_new_fmlp(void)
594 return &sem->litmus_lock; 641 return &sem->litmus_lock;
595} 642}
596 643
597static struct dynamic_group_lock* psnedf_new_dgl(void) 644static struct litmus_lock* psnedf_new_dgl(void)
598{ 645{
599 struct dgl_semaphore* sem; 646 struct dgl_semaphore* sem;
600 647
@@ -605,18 +652,19 @@ static struct dynamic_group_lock* psnedf_new_dgl(void)
605 sem->resource_holders = 0; 652 sem->resource_holders = 0;
606 sem->dgl_resources = 0; 653 sem->dgl_resources = 0;
607 init_waitqueue_head(&sem->wait); 654 init_waitqueue_head(&sem->wait);
608 //sem->dynamic_group_lock.ops = &psnedf_dgl_lock_ops; 655 sem->litmus_lock.ops = &psnedf_dgl_lock_ops;
609 return &sem->dynamic_group_lock; 656 return &sem->litmus_lock;
610} 657}
611 658
612/* **** lock constructor **** */ 659/* **** lock constructor **** */
613 660
614 661
615static long psnedf_allocate_lock(struct litmus_lock **lock, int type, 662static long psnedf_allocate_lock(struct litmus_lock **lock, int type,
616 void* __user unused) 663 void* __user config)
617{ 664{
618 int err = -ENXIO; 665 int err = -ENXIO;
619 struct srp_semaphore* srp; 666 struct srp_semaphore* srp;
667 struct od_table_entry* entry;
620 668
621 /* PSN-EDF currently supports the SRP for local resources and the FMLP 669 /* PSN-EDF currently supports the SRP for local resources and the FMLP
622 * for global resources. */ 670 * for global resources. */
@@ -639,6 +687,33 @@ static long psnedf_allocate_lock(struct litmus_lock **lock, int type,
639 } else 687 } else
640 err = -ENOMEM; 688 err = -ENOMEM;
641 break; 689 break;
690
691 case DGL_SEM:
692 /* assume that config is an int, and that config < 0 means create a new DGL
693 * and that a config > 0 means point this resource to the existing DGL
694 * for the resource in entry number config.
695 */
696 TRACE("config: %d\n", *(int*)(config));
697 if (*(int*)(config) < 0){
698 *lock = psnedf_new_dgl();
699 if (*lock)
700 err = 0;
701 else
702 err = -ENOMEM;
703 /* In this case, we are adding a resource to an existing lock */
704 } else {
705 entry = get_entry_for_od(*(int*)(config));
706 if (entry && entry->obj && entry->obj->type == DGL_SEM){
707 *lock = (struct litmus_lock*) entry->obj->obj;
708 err = 0;
709 } else {
710 err = -EINVAL;
711 printk(KERN_DEBUG "Cannot add to that group!\n");
712 while(1);
713 }
714 }
715
716 break;
642 }; 717 };
643 718
644 return err; 719 return err;
@@ -646,7 +721,6 @@ static long psnedf_allocate_lock(struct litmus_lock **lock, int type,
646 721
647#endif 722#endif
648 723
649
650static long psnedf_activate_plugin(void) 724static long psnedf_activate_plugin(void)
651{ 725{
652#ifdef CONFIG_RELEASE_MASTER 726#ifdef CONFIG_RELEASE_MASTER