]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - ipc/util.h
memcontrol: move oom task exclusion to tasklist scan
[linux-2.6-omap-h63xx.git] / ipc / util.h
index fa7e7a07486eb21f0051c2cb854546ccd2c16559..9ffea40457cedb17eca4cc9df13ed1b3a5f1a3f7 100644 (file)
@@ -32,7 +32,7 @@ struct ipc_ids {
        int in_use;
        unsigned short seq;
        unsigned short seq_max;
-       struct mutex mutex;
+       struct rw_semaphore rw_mutex;
        struct idr ipcs_idr;
 };
 
@@ -54,7 +54,7 @@ struct ipc_params {
  * the calls to sys_msgget(), sys_semget(), sys_shmget()
  *      . routine to call to create a new ipc object. Can be one of newque,
  *        newary, newseg
- *      . routine to call to call to check permissions for a new ipc object.
+ *      . routine to call to check permissions for a new ipc object.
  *        Can be one of security_msg_associate, security_sem_associate,
  *        security_shm_associate
  *      . routine to call for an extra check if needed
@@ -81,14 +81,17 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
 
 #define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER)
 
-/* must be called with ids->mutex acquired.*/
+/* must be called with ids->rw_mutex acquired for writing */
 int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
+
+/* must be called with ids->rw_mutex acquired for reading */
 int ipc_get_maxid(struct ipc_ids *);
 
 /* must be called with both locks acquired. */
 void ipc_rmid(struct ipc_ids *, struct kern_ipc_perm *);
 
-int ipcperms (struct kern_ipc_perm *ipcp, short flg);
+/* must be called with ipcp locked */
+int ipcperms(struct kern_ipc_perm *ipcp, short flg);
 
 /* for rare, potentially huge allocations.
  * both function can sleep
@@ -106,8 +109,12 @@ void* ipc_rcu_alloc(int size);
 void ipc_rcu_getref(void *ptr);
 void ipc_rcu_putref(void *ptr);
 
+/*
+ * ipc_lock_down: called with rw_mutex held
+ * ipc_lock: called without that lock held
+ */
+struct kern_ipc_perm *ipc_lock_down(struct ipc_ids *, int);
 struct kern_ipc_perm *ipc_lock(struct ipc_ids *, int);
-int ipc_buildid(struct ipc_ids* ids, int id, int seq);
 
 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);
@@ -127,8 +134,15 @@ extern int ipcget_new(struct ipc_namespace *, struct ipc_ids *,
 extern int ipcget_public(struct ipc_namespace *, struct ipc_ids *,
                        struct ipc_ops *, struct ipc_params *);
 
-static inline int ipc_checkid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp,
-                               int uid)
+static inline int ipc_buildid(int id, int seq)
+{
+       return SEQ_MULTIPLIER * seq + id;
+}
+
+/*
+ * Must be called with ipcp locked
+ */
+static inline int ipc_checkid(struct kern_ipc_perm *ipcp, int uid)
 {
        if (uid / SEQ_MULTIPLIER != ipcp->seq)
                return 1;
@@ -147,6 +161,23 @@ static inline void ipc_unlock(struct kern_ipc_perm *perm)
        rcu_read_unlock();
 }
 
+static inline struct kern_ipc_perm *ipc_lock_check_down(struct ipc_ids *ids,
+                                               int id)
+{
+       struct kern_ipc_perm *out;
+
+       out = ipc_lock_down(ids, id);
+       if (IS_ERR(out))
+               return out;
+
+       if (ipc_checkid(out, id)) {
+               ipc_unlock(out);
+               return ERR_PTR(-EIDRM);
+       }
+
+       return out;
+}
+
 static inline struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids,
                                                int id)
 {
@@ -156,7 +187,7 @@ static inline struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids,
        if (IS_ERR(out))
                return out;
 
-       if (ipc_checkid(ids, out, id)) {
+       if (ipc_checkid(out, id)) {
                ipc_unlock(out);
                return ERR_PTR(-EIDRM);
        }
@@ -164,6 +195,16 @@ static inline struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids,
        return out;
 }
 
+/**
+ * ipcget - Common sys_*get() code
+ * @ns : namsepace
+ * @ids : IPC identifier set
+ * @ops : operations to be called on ipc object creation, permission checks
+ *        and further checks
+ * @params : the parameters needed by the previous operations.
+ *
+ * Common routine called by sys_msgget(), sys_semget() and sys_shmget().
+ */
 static inline int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
                        struct ipc_ops *ops, struct ipc_params *params)
 {