From: Guru Anbalagane Date: Tue, 13 Sep 2011 19:09:55 +0000 (-0700) Subject: Revert "use rwlocks for ipc" X-Git-Tag: v2.6.39-400.9.0~914 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=64f3733a715e9b397a57803ebd36dd97ac1f0fcf;p=users%2Fjedix%2Flinux-maple.git Revert "use rwlocks for ipc" This reverts commit 78fe45325c8e2e3f4b6ebb1ee15b6c2e8af5ddb1. --- diff --git a/include/linux/ipc.h b/include/linux/ipc.h index e7def7b18e8a..3b1594d662b0 100644 --- a/include/linux/ipc.h +++ b/include/linux/ipc.h @@ -85,7 +85,7 @@ struct ipc_kludge { /* used by in-kernel data structures */ struct kern_ipc_perm { - rwlock_t lock; + spinlock_t lock; int deleted; int id; key_t key; diff --git a/ipc/sem.c b/ipc/sem.c index 2df779307fb5..d34316d8a924 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -95,7 +95,6 @@ #define sem_ids(ns) ((ns)->ids[IPC_SEM_IDS]) #define sem_unlock(sma) ipc_unlock(&(sma)->sem_perm) -#define sem_read_unlock(sma) ipc_read_unlock(&(sma)->sem_perm) #define sem_checkid(sma, semid) ipc_checkid(&sma->sem_perm, semid) static int newary(struct ipc_namespace *, struct ipc_params *); @@ -172,17 +171,6 @@ static inline struct sem_array *sem_lock_check(struct ipc_namespace *ns, return container_of(ipcp, struct sem_array, sem_perm); } -static inline struct sem_array *sem_read_lock_check(struct ipc_namespace *ns, - int id) -{ - struct kern_ipc_perm *ipcp = ipc_read_lock_check(&sem_ids(ns), id); - - if (IS_ERR(ipcp)) - return (struct sem_array *)ipcp; - - return container_of(ipcp, struct sem_array, sem_perm); -} - static inline void sem_lock_and_putref(struct sem_array *sma) { ipc_lock_by_ptr(&sma->sem_perm); @@ -195,17 +183,11 @@ static inline void sem_getref_and_unlock(struct sem_array *sma) ipc_unlock(&(sma)->sem_perm); } -static inline void sem_getref_and_read_unlock(struct sem_array *sma) -{ - ipc_rcu_getref(sma); - ipc_read_unlock(&(sma)->sem_perm); -} - static inline void sem_putref(struct sem_array *sma) { - rcu_read_lock(); + ipc_lock_by_ptr(&sma->sem_perm); ipc_rcu_putref(sma); - rcu_read_unlock(); + ipc_unlock(&(sma)->sem_perm); } static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s) @@ -793,7 +775,7 @@ static void freeary(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) int i; /* Free the existing undo structures for this semaphore set. */ - //assert_spin_locked(&sma->sem_perm.lock); + assert_spin_locked(&sma->sem_perm.lock); list_for_each_entry_safe(un, tu, &sma->list_id, list_id) { list_del(&un->list_id); spin_lock(&un->ulp->lock); @@ -1038,7 +1020,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum, spin_unlock(&curr->lock); } - //assert_spin_locked(&sma->sem_perm.lock); + assert_spin_locked(&sma->sem_perm.lock); list_for_each_entry(un, &sma->list_id, list_id) { for (i = 0; i < nsems; i++) un->semadj[i] = 0; @@ -1080,7 +1062,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum, if (val > SEMVMX || val < 0) goto out_unlock; - //assert_spin_locked(&sma->sem_perm.lock); + assert_spin_locked(&sma->sem_perm.lock); list_for_each_entry(un, &sma->list_id, list_id) un->semadj[semnum] = 0; @@ -1352,7 +1334,7 @@ static struct sem_undo *find_alloc_undo(struct ipc_namespace *ns, int semid) new->semid = semid; assert_spin_locked(&ulp->lock); list_add_rcu(&new->list_proc, &ulp->list_proc); - //assert_spin_locked(&sma->sem_perm.lock); + assert_spin_locked(&sma->sem_perm.lock); list_add(&new->list_id, &sma->list_id); un = new; @@ -1525,7 +1507,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, INIT_LIST_HEAD(&tasks); - sma = sem_read_lock_check(ns, semid); + sma = sem_lock_check(ns, semid); if (IS_ERR(sma)) { if (un) rcu_read_unlock(); @@ -1576,7 +1558,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, * per-semaphore locks instead. */ if (!un) - sem_getref_and_read_unlock(sma); + sem_getref_and_unlock(sma); error = try_atomic_semop (sma, sops, nsops, un, task_tgid_vnr(current), &pending, &blocker); @@ -1620,7 +1602,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, spin_unlock(&blocker->lock); if (un) - sem_getref_and_read_unlock(sma); + sem_getref_and_unlock(sma); if (timeout) jiffies_left = schedule_timeout(jiffies_left); @@ -1697,7 +1679,7 @@ out_putref: goto out_wakeup; out_unlock_free: - sem_read_unlock(sma); + sem_unlock(sma); out_wakeup: wake_up_sem_queue_do(&tasks); out_free: @@ -1795,7 +1777,7 @@ void exit_sem(struct task_struct *tsk) } /* remove un from the linked lists */ - //assert_spin_locked(&sma->sem_perm.lock); + assert_spin_locked(&sma->sem_perm.lock); list_del(&un->list_id); spin_lock(&ulp->lock); diff --git a/ipc/util.c b/ipc/util.c index d60930ed0285..5c0d28921ba8 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -259,14 +259,14 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) if (ids->in_use >= size) return -ENOSPC; - rwlock_init(&new->lock); + spin_lock_init(&new->lock); new->deleted = 0; rcu_read_lock(); - write_lock(&new->lock); + spin_lock(&new->lock); err = idr_get_new(&ids->ipcs_idr, new, &id); if (err) { - write_unlock(&new->lock); + spin_unlock(&new->lock); rcu_read_unlock(); return err; } @@ -481,7 +481,7 @@ void ipc_free(void* ptr, int size) */ struct ipc_rcu_hdr { - atomic_t refcount; + int refcount; int is_vmalloc; void *data[0]; }; @@ -535,14 +535,14 @@ void* ipc_rcu_alloc(int size) if (out) { out += HDRLEN_VMALLOC; container_of(out, struct ipc_rcu_hdr, data)->is_vmalloc = 1; - atomic_set(&container_of(out, struct ipc_rcu_hdr, data)->refcount, 1); + container_of(out, struct ipc_rcu_hdr, data)->refcount = 1; } } else { out = kmalloc(HDRLEN_KMALLOC + size, GFP_KERNEL); if (out) { out += HDRLEN_KMALLOC; container_of(out, struct ipc_rcu_hdr, data)->is_vmalloc = 0; - atomic_set(&container_of(out, struct ipc_rcu_hdr, data)->refcount, 1); + container_of(out, struct ipc_rcu_hdr, data)->refcount = 1; } } @@ -551,7 +551,7 @@ void* ipc_rcu_alloc(int size) void ipc_rcu_getref(void *ptr) { - atomic_inc(&container_of(ptr, struct ipc_rcu_hdr, data)->refcount); + container_of(ptr, struct ipc_rcu_hdr, data)->refcount++; } static void ipc_do_vfree(struct work_struct *work) @@ -594,7 +594,7 @@ static void ipc_immediate_free(struct rcu_head *head) void ipc_rcu_putref(void *ptr) { - if (!atomic_dec_and_test(&container_of(ptr, struct ipc_rcu_hdr, data)->refcount)) + if (--container_of(ptr, struct ipc_rcu_hdr, data)->refcount > 0) return; if (container_of(ptr, struct ipc_rcu_hdr, data)->is_vmalloc) { @@ -707,39 +707,13 @@ struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id) return ERR_PTR(-EINVAL); } - write_lock(&out->lock); + 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) { - write_unlock(&out->lock); - rcu_read_unlock(); - return ERR_PTR(-EINVAL); - } - - return out; -} - -struct kern_ipc_perm *ipc_read_lock(struct ipc_ids *ids, int id) -{ - struct kern_ipc_perm *out; - int lid = ipcid_to_idx(id); - - rcu_read_lock(); - out = idr_find(&ids->ipcs_idr, lid); - if (out == NULL) { - rcu_read_unlock(); - return ERR_PTR(-EINVAL); - } - - read_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) { - read_unlock(&out->lock); + spin_unlock(&out->lock); rcu_read_unlock(); return ERR_PTR(-EINVAL); } @@ -763,22 +737,6 @@ struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id) return out; } -struct kern_ipc_perm *ipc_read_lock_check(struct ipc_ids *ids, int id) -{ - struct kern_ipc_perm *out; - - out = ipc_read_lock(ids, id); - if (IS_ERR(out)) - return out; - - if (ipc_checkid(out, id)) { - ipc_read_unlock(out); - return ERR_PTR(-EIDRM); - } - - return out; -} - /** * ipcget - Common sys_*get() code * @ns : namsepace diff --git a/ipc/util.h b/ipc/util.h index 25e9808bac68..6f5c20bedaab 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -161,23 +161,16 @@ static inline int ipc_checkid(struct kern_ipc_perm *ipcp, int uid) static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm) { rcu_read_lock(); - write_lock(&perm->lock); + spin_lock(&perm->lock); } static inline void ipc_unlock(struct kern_ipc_perm *perm) { - write_unlock(&perm->lock); - rcu_read_unlock(); -} - -static inline void ipc_read_unlock(struct kern_ipc_perm *perm) -{ - read_unlock(&perm->lock); + spin_unlock(&perm->lock); rcu_read_unlock(); } struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id); -struct kern_ipc_perm *ipc_read_lock_check(struct ipc_ids *ids, int id); int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, struct ipc_ops *ops, struct ipc_params *params); void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,