diff options
author | Andrew Morton <akpm@digeo.com> | 2002-10-31 04:10:03 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-10-31 04:10:03 -0800 |
commit | 8f2215c6a1d2120850959e48dd9933fc7b4e5547 (patch) | |
tree | 596be394f8b83c283f92c735c88a5dc4ef9d3559 /ipc | |
parent | bb468c02496de13352bd607ff91fab1207edf01f (diff) | |
download | history-8f2215c6a1d2120850959e48dd9933fc7b4e5547.tar.gz |
[PATCH] uninlining in ipc/*
Uninlines some large functions in the ipc code.
Before:
text data bss dec hex filename
30226 224 192 30642 77b2 ipc/built-in.o
After:
text data bss dec hex filename
20274 224 192 20690 50d2 ipc/built-in.o
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/util.c | 72 | ||||
-rw-r--r-- | ipc/util.h | 77 |
2 files changed, 77 insertions, 72 deletions
diff --git a/ipc/util.c b/ipc/util.c index 4b7f324d91254b..fc381e57325442 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -22,6 +22,7 @@ #include <linux/slab.h> #include <linux/highuid.h> #include <linux/security.h> +#include <linux/rcupdate.h> #include <linux/workqueue.h> #if defined(CONFIG_SYSVIPC) @@ -406,6 +407,77 @@ void ipc64_perm_to_ipc_perm (struct ipc64_perm *in, struct ipc_perm *out) out->seq = in->seq; } +/* + * ipc_get() requires ipc_ids.sem down, otherwise we need a rmb() here + * to sync with grow_ary(); + * + * So far only shm_get_stat() uses ipc_get() via shm_get(). So ipc_get() + * is called with shm_ids.sem locked. Thus a rmb() is not needed here, + * as grow_ary() also requires shm_ids.sem down(for shm). + * + * But if ipc_get() is used in the future without ipc_ids.sem down, + * we need to add a rmb() before accessing the entries array + */ +struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id) +{ + struct kern_ipc_perm* out; + int lid = id % SEQ_MULTIPLIER; + if(lid >= ids->size) + return NULL; + rmb(); + out = ids->entries[lid].p; + return out; +} + +struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id) +{ + struct kern_ipc_perm* out; + int lid = id % SEQ_MULTIPLIER; + + rcu_read_lock(); + if(lid >= ids->size) { + rcu_read_unlock(); + return NULL; + } + + /* we need a barrier here to sync with grow_ary() */ + rmb(); + out = ids->entries[lid].p; + if(out == NULL) { + rcu_read_unlock(); + return NULL; + } + spin_lock(&out->lock); + + /* ipc_rmid() may have already freed the ID while ipc_lock + * was spinning: here verify that the structure is still valid + */ + if (out->deleted) { + spin_unlock(&out->lock); + rcu_read_unlock(); + return NULL; + } + return out; +} + +void ipc_unlock(struct kern_ipc_perm* perm) +{ + spin_unlock(&perm->lock); + rcu_read_unlock(); +} + +int ipc_buildid(struct ipc_ids* ids, int id, int seq) +{ + return SEQ_MULTIPLIER*seq + id; +} + +int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid) +{ + if(uid/SEQ_MULTIPLIER != ipcp->seq) + return 1; + return 0; +} + #ifndef __ia64__ /** diff --git a/ipc/util.h b/ipc/util.h index 100cdc706b02d3..f4d418587a9648 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -4,8 +4,6 @@ * * ipc helper functions (c) 1999 Manfred Spraul <manfreds@colorfullife.com> */ -#include <linux/rcupdate.h> - #define USHRT_MAX 0xffff #define SEQ_MULTIPLIER (IPCMNI) @@ -49,76 +47,11 @@ void ipc_free(void* ptr, int size); void* ipc_rcu_alloc(int size); void ipc_rcu_free(void* arg, int size); -/* - * ipc_get() requires ipc_ids.sem down, otherwise we need a rmb() here - * to sync with grow_ary(); - * - * So far only shm_get_stat() uses ipc_get() via shm_get(). So ipc_get() - * is called with shm_ids.sem locked. Thus a rmb() is not needed here, - * as grow_ary() also requires shm_ids.sem down(for shm). - * - * But if ipc_get() is used in the future without ipc_ids.sem down, - * we need to add a rmb() before accessing the entries array - */ -extern inline struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id) -{ - struct kern_ipc_perm* out; - int lid = id % SEQ_MULTIPLIER; - if(lid >= ids->size) - return NULL; - rmb(); - out = ids->entries[lid].p; - return out; -} - -extern inline struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id) -{ - struct kern_ipc_perm* out; - int lid = id % SEQ_MULTIPLIER; - - rcu_read_lock(); - if(lid >= ids->size) { - rcu_read_unlock(); - return NULL; - } - - /* we need a barrier here to sync with grow_ary() */ - rmb(); - out = ids->entries[lid].p; - if(out == NULL) { - rcu_read_unlock(); - return NULL; - } - spin_lock(&out->lock); - - /* ipc_rmid() may have already freed the ID while ipc_lock - * was spinning: here verify that the structure is still valid - */ - if (out->deleted) { - spin_unlock(&out->lock); - rcu_read_unlock(); - return NULL; - } - return out; -} - -extern inline void ipc_unlock(struct kern_ipc_perm* perm) -{ - spin_unlock(&perm->lock); - rcu_read_unlock(); -} - -extern inline int ipc_buildid(struct ipc_ids* ids, int id, int seq) -{ - return SEQ_MULTIPLIER*seq + id; -} - -extern inline int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid) -{ - if(uid/SEQ_MULTIPLIER != ipcp->seq) - return 1; - return 0; -} +struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id); +struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id); +void ipc_unlock(struct kern_ipc_perm* perm); +int ipc_buildid(struct ipc_ids* ids, int id, int seq); +int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid); void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out); void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out); |