aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2011-01-29 15:50:52 -0500
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2011-02-01 16:53:21 -0500
commit7f0bd4c213ff8dca0eb3bdd887f5c62c8d30fab5 (patch)
tree99b45b5466dc27308e6d65751baf5e109eb37385
parentfab768a4cdc49ad7886cac0d0361f8432965a817 (diff)
fdso: pass userpsace config argument to object constructor
As Glenn pointed out, it is useful for some protocols (e.g., k-exclusion protocols) to know the userspace configuration at object creation time. This patch changes the fdso API to pass the parameter to the object constructor, which is then in turn passed to the lock allocater. The return code from the lock allocater is passed to userspace in return. This also fixes some null pointer dereferences in the FDSO code found by the test suite in liblitmus.
-rw-r--r--include/litmus/fdso.h2
-rw-r--r--include/litmus/sched_plugin.h3
-rw-r--r--litmus/fdso.c51
-rw-r--r--litmus/locking.c11
-rw-r--r--litmus/sched_gsn_edf.c3
-rw-r--r--litmus/sched_plugin.c3
-rw-r--r--litmus/sched_psn_edf.c3
7 files changed, 46 insertions, 30 deletions
diff --git a/include/litmus/fdso.h b/include/litmus/fdso.h
index 25a292d68d96..caf2a1e6918c 100644
--- a/include/litmus/fdso.h
+++ b/include/litmus/fdso.h
@@ -43,7 +43,7 @@ struct od_table_entry {
43}; 43};
44 44
45struct fdso_ops { 45struct fdso_ops {
46 void* (*create)(obj_type_t type); 46 int (*create)(void** obj_ref, obj_type_t type, void* __user);
47 void (*destroy)(obj_type_t type, void*); 47 void (*destroy)(obj_type_t type, void*);
48 int (*open) (struct od_table_entry*, void* __user); 48 int (*open) (struct od_table_entry*, void* __user);
49 int (*close) (struct od_table_entry*); 49 int (*close) (struct od_table_entry*);
diff --git a/include/litmus/sched_plugin.h b/include/litmus/sched_plugin.h
index 8a3ed6d19a3c..6e7cabdddae8 100644
--- a/include/litmus/sched_plugin.h
+++ b/include/litmus/sched_plugin.h
@@ -55,7 +55,8 @@ typedef void (*task_exit_t) (struct task_struct *);
55 55
56/* Called when the current task attempts to create a new lock of a given 56/* Called when the current task attempts to create a new lock of a given
57 * protocol type. */ 57 * protocol type. */
58typedef long (*allocate_lock_t) (struct litmus_lock **lock, int type); 58typedef long (*allocate_lock_t) (struct litmus_lock **lock, int type,
59 void* __user config);
59 60
60 61
61/********************* sys call backends ********************/ 62/********************* sys call backends ********************/
diff --git a/litmus/fdso.c b/litmus/fdso.c
index b3a95f13d651..aa7b384264e3 100644
--- a/litmus/fdso.c
+++ b/litmus/fdso.c
@@ -25,12 +25,12 @@ static const struct fdso_ops* fdso_ops[] = {
25 &generic_lock_ops, /* SRP_SEM */ 25 &generic_lock_ops, /* SRP_SEM */
26}; 26};
27 27
28static void* fdso_create(obj_type_t type) 28static int fdso_create(void** obj_ref, obj_type_t type, void* __user config)
29{ 29{
30 if (fdso_ops[type]->create) 30 if (fdso_ops[type]->create)
31 return fdso_ops[type]->create(type); 31 return fdso_ops[type]->create(obj_ref, type, config);
32 else 32 else
33 return NULL; 33 return -EINVAL;
34} 34}
35 35
36static void fdso_destroy(obj_type_t type, void* obj) 36static void fdso_destroy(obj_type_t type, void* obj)
@@ -55,20 +55,27 @@ static int fdso_close(struct od_table_entry* entry)
55} 55}
56 56
57/* inode must be locked already */ 57/* inode must be locked already */
58static struct inode_obj_id* alloc_inode_obj(struct inode* inode, 58static int alloc_inode_obj(struct inode_obj_id** obj_ref,
59 obj_type_t type, 59 struct inode* inode,
60 unsigned int id) 60 obj_type_t type,
61 unsigned int id,
62 void* __user config)
61{ 63{
62 struct inode_obj_id* obj; 64 struct inode_obj_id* obj;
63 void* raw_obj; 65 void* raw_obj;
64 66 int err;
65 raw_obj = fdso_create(type);
66 if (!raw_obj)
67 return NULL;
68 67
69 obj = kmalloc(sizeof(*obj), GFP_KERNEL); 68 obj = kmalloc(sizeof(*obj), GFP_KERNEL);
70 if (!obj) 69 if (!obj) {
71 return NULL; 70 return -ENOMEM;
71 }
72
73 err = fdso_create(&raw_obj, type, config);
74 if (err != 0) {
75 kfree(obj);
76 return err;
77 }
78
72 INIT_LIST_HEAD(&obj->list); 79 INIT_LIST_HEAD(&obj->list);
73 atomic_set(&obj->count, 1); 80 atomic_set(&obj->count, 1);
74 obj->type = type; 81 obj->type = type;
@@ -80,7 +87,9 @@ static struct inode_obj_id* alloc_inode_obj(struct inode* inode,
80 atomic_inc(&inode->i_count); 87 atomic_inc(&inode->i_count);
81 88
82 printk(KERN_DEBUG "alloc_inode_obj(%p, %d, %d): object created\n", inode, type, id); 89 printk(KERN_DEBUG "alloc_inode_obj(%p, %d, %d): object created\n", inode, type, id);
83 return obj; 90
91 *obj_ref = obj;
92 return 0;
84} 93}
85 94
86/* inode must be locked already */ 95/* inode must be locked already */
@@ -169,7 +178,7 @@ void exit_od_table(struct task_struct* t)
169static int do_sys_od_open(struct file* file, obj_type_t type, int id, 178static int do_sys_od_open(struct file* file, obj_type_t type, int id,
170 void* __user config) 179 void* __user config)
171{ 180{
172 int idx = 0, err; 181 int idx = 0, err = 0;
173 struct inode* inode; 182 struct inode* inode;
174 struct inode_obj_id* obj = NULL; 183 struct inode_obj_id* obj = NULL;
175 struct od_table_entry* entry; 184 struct od_table_entry* entry;
@@ -183,9 +192,10 @@ static int do_sys_od_open(struct file* file, obj_type_t type, int id,
183 mutex_lock(&inode->i_obj_mutex); 192 mutex_lock(&inode->i_obj_mutex);
184 obj = get_inode_obj(inode, type, id); 193 obj = get_inode_obj(inode, type, id);
185 if (!obj) 194 if (!obj)
186 obj = alloc_inode_obj(inode, type, id); 195 err = alloc_inode_obj(&obj, inode, type, id, config);
187 if (!obj) { 196 if (err != 0) {
188 idx = -ENOMEM; 197 obj = NULL;
198 idx = err;
189 entry->used = 0; 199 entry->used = 0;
190 } else { 200 } else {
191 entry->obj = obj; 201 entry->obj = obj;
@@ -195,12 +205,15 @@ static int do_sys_od_open(struct file* file, obj_type_t type, int id,
195 205
196 mutex_unlock(&inode->i_obj_mutex); 206 mutex_unlock(&inode->i_obj_mutex);
197 207
198 err = fdso_open(entry, config); 208 /* open only if creation succeeded */
209 if (!err)
210 err = fdso_open(entry, config);
199 if (err < 0) { 211 if (err < 0) {
200 /* The class rejected the open call. 212 /* The class rejected the open call.
201 * We need to clean up and tell user space. 213 * We need to clean up and tell user space.
202 */ 214 */
203 put_od_entry(entry); 215 if (obj)
216 put_od_entry(entry);
204 idx = err; 217 idx = err;
205 } 218 }
206 219
diff --git a/litmus/locking.c b/litmus/locking.c
index d39afaeefffe..8ee6a6b68009 100644
--- a/litmus/locking.c
+++ b/litmus/locking.c
@@ -5,7 +5,7 @@
5#include <litmus/sched_plugin.h> 5#include <litmus/sched_plugin.h>
6#include <litmus/trace.h> 6#include <litmus/trace.h>
7 7
8static void* create_generic_lock(obj_type_t type); 8static int create_generic_lock(void** obj_ref, obj_type_t type, void* __user arg);
9static int open_generic_lock(struct od_table_entry* entry, void* __user arg); 9static int open_generic_lock(struct od_table_entry* entry, void* __user arg);
10static int close_generic_lock(struct od_table_entry* entry); 10static int close_generic_lock(struct od_table_entry* entry);
11static void destroy_generic_lock(obj_type_t type, void* sem); 11static void destroy_generic_lock(obj_type_t type, void* sem);
@@ -28,16 +28,15 @@ static inline struct litmus_lock* get_lock(struct od_table_entry* entry)
28 return (struct litmus_lock*) entry->obj->obj; 28 return (struct litmus_lock*) entry->obj->obj;
29} 29}
30 30
31static void* create_generic_lock(obj_type_t type) 31static int create_generic_lock(void** obj_ref, obj_type_t type, void* __user arg)
32{ 32{
33 struct litmus_lock* lock; 33 struct litmus_lock* lock;
34 int err; 34 int err;
35 35
36 err = litmus->allocate_lock(&lock, type); 36 err = litmus->allocate_lock(&lock, type, arg);
37 if (err == 0) 37 if (err == 0)
38 return lock; 38 *obj_ref = lock;
39 else 39 return err;
40 return NULL;
41} 40}
42 41
43static int open_generic_lock(struct od_table_entry* entry, void* __user arg) 42static int open_generic_lock(struct od_table_entry* entry, void* __user arg)
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c
index c525d43eb051..c5c9600c33d8 100644
--- a/litmus/sched_gsn_edf.c
+++ b/litmus/sched_gsn_edf.c
@@ -895,7 +895,8 @@ static struct litmus_lock* gsnedf_new_fmlp(void)
895/* **** lock constructor **** */ 895/* **** lock constructor **** */
896 896
897 897
898static long gsnedf_allocate_lock(struct litmus_lock **lock, int type) 898static long gsnedf_allocate_lock(struct litmus_lock **lock, int type,
899 void* __user unused)
899{ 900{
900 int err = -ENXIO; 901 int err = -ENXIO;
901 902
diff --git a/litmus/sched_plugin.c b/litmus/sched_plugin.c
index 2f8f399b195f..d54886df1f57 100644
--- a/litmus/sched_plugin.c
+++ b/litmus/sched_plugin.c
@@ -123,7 +123,8 @@ static long litmus_dummy_deactivate_plugin(void)
123 123
124#ifdef CONFIG_LITMUS_LOCKING 124#ifdef CONFIG_LITMUS_LOCKING
125 125
126static long litmus_dummy_allocate_lock(struct litmus_lock **lock, int type) 126static long litmus_dummy_allocate_lock(struct litmus_lock **lock, int type,
127 void* __user config)
127{ 128{
128 return -ENXIO; 129 return -ENXIO;
129} 130}
diff --git a/litmus/sched_psn_edf.c b/litmus/sched_psn_edf.c
index 801bc92c5835..abb06fa53e3a 100644
--- a/litmus/sched_psn_edf.c
+++ b/litmus/sched_psn_edf.c
@@ -547,7 +547,8 @@ static struct litmus_lock* psnedf_new_fmlp(void)
547/* **** lock constructor **** */ 547/* **** lock constructor **** */
548 548
549 549
550static long psnedf_allocate_lock(struct litmus_lock **lock, int type) 550static long psnedf_allocate_lock(struct litmus_lock **lock, int type,
551 void* __user unused)
551{ 552{
552 int err = -ENXIO; 553 int err = -ENXIO;
553 struct srp_semaphore* srp; 554 struct srp_semaphore* srp;