aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/util.h
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/util.h')
-rw-r--r--ipc/util.h28
1 files changed, 21 insertions, 7 deletions
diff --git a/ipc/util.h b/ipc/util.h
index 59d78aa94987..9c47d6f6c7b4 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -15,9 +15,9 @@
15 15
16#define SEQ_MULTIPLIER (IPCMNI) 16#define SEQ_MULTIPLIER (IPCMNI)
17 17
18void sem_init (void); 18void sem_init(void);
19void msg_init (void); 19void msg_init(void);
20void shm_init (void); 20void shm_init(void);
21 21
22struct ipc_namespace; 22struct ipc_namespace;
23 23
@@ -100,6 +100,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
100 100
101#define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER) 101#define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER)
102#define ipcid_to_seqx(id) ((id) / SEQ_MULTIPLIER) 102#define ipcid_to_seqx(id) ((id) / SEQ_MULTIPLIER)
103#define IPCID_SEQ_MAX min_t(int, INT_MAX/SEQ_MULTIPLIER, USHRT_MAX)
103 104
104/* must be called with ids->rwsem acquired for writing */ 105/* must be called with ids->rwsem acquired for writing */
105int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int); 106int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
@@ -116,8 +117,8 @@ int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flg);
116/* for rare, potentially huge allocations. 117/* for rare, potentially huge allocations.
117 * both function can sleep 118 * both function can sleep
118 */ 119 */
119void* ipc_alloc(int size); 120void *ipc_alloc(int size);
120void ipc_free(void* ptr, int size); 121void ipc_free(void *ptr, int size);
121 122
122/* 123/*
123 * For allocation that need to be freed by RCU. 124 * For allocation that need to be freed by RCU.
@@ -125,7 +126,7 @@ void ipc_free(void* ptr, int size);
125 * getref increases the refcount, the putref call that reduces the recount 126 * getref increases the refcount, the putref call that reduces the recount
126 * to 0 schedules the rcu destruction. Caller must guarantee locking. 127 * to 0 schedules the rcu destruction. Caller must guarantee locking.
127 */ 128 */
128void* ipc_rcu_alloc(int size); 129void *ipc_rcu_alloc(int size);
129int ipc_rcu_getref(void *ptr); 130int ipc_rcu_getref(void *ptr);
130void ipc_rcu_putref(void *ptr, void (*func)(struct rcu_head *head)); 131void ipc_rcu_putref(void *ptr, void (*func)(struct rcu_head *head));
131void ipc_rcu_free(struct rcu_head *head); 132void ipc_rcu_free(struct rcu_head *head);
@@ -144,7 +145,7 @@ struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
144 /* On IA-64, we always use the "64-bit version" of the IPC structures. */ 145 /* On IA-64, we always use the "64-bit version" of the IPC structures. */
145# define ipc_parse_version(cmd) IPC_64 146# define ipc_parse_version(cmd) IPC_64
146#else 147#else
147int ipc_parse_version (int *cmd); 148int ipc_parse_version(int *cmd);
148#endif 149#endif
149 150
150extern void free_msg(struct msg_msg *msg); 151extern void free_msg(struct msg_msg *msg);
@@ -185,6 +186,19 @@ static inline void ipc_unlock(struct kern_ipc_perm *perm)
185 rcu_read_unlock(); 186 rcu_read_unlock();
186} 187}
187 188
189/*
190 * ipc_valid_object() - helper to sort out IPC_RMID races for codepaths
191 * where the respective ipc_ids.rwsem is not being held down.
192 * Checks whether the ipc object is still around or if it's gone already, as
193 * ipc_rmid() may have already freed the ID while the ipc lock was spinning.
194 * Needs to be called with kern_ipc_perm.lock held -- exception made for one
195 * checkpoint case at sys_semtimedop() as noted in code commentary.
196 */
197static inline bool ipc_valid_object(struct kern_ipc_perm *perm)
198{
199 return !perm->deleted;
200}
201
188struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id); 202struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id);
189int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, 203int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
190 struct ipc_ops *ops, struct ipc_params *params); 204 struct ipc_ops *ops, struct ipc_params *params);