[SSI] openssi/kernel/include/cluster/ssi/ipc unixnm.h,1.13,1.14
Roger Tsang <[email protected]>
| Newsgroups | gmane.linux.cluster.ssic.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/ssic-linux/openssi/kernel/include/cluster/ssi/ipc
In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv16276/include/cluster/ssi/ipc
Modified Files:
Tag: OPENSSI-FC
unixnm.h
Log Message:
IPC:
- Regression:
- rmtunix_socket_info structure lookup race. (#ifdef RCU_RMTUNIX_CACHE)
- missing sock_hold() for rmtunix_cache_info(). (#ifdef IPC_STALE_RMTUNIX_CACHE_FIX)
cluster/ssi/cfs/cfs_ipcshm.c | 4 -
cluster/ssi/cfs/svrcfs.c | 37 +++++----------
cluster/ssi/ipc/rmtunix.c | 14 +----
cluster/ssi/vproc/vp_subr.c | 5 --
include/cluster/ssi/ipc/unixnm.h | 93 ++++++++++++++++++++++++---------------
include/cluster/ssi/unix.h | 34 ++------------
include/linux/config.h | 5 +-
7 files changed, 83 insertions(+), 109 deletions(-)
Index: unixnm.h
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/include/cluster/ssi/ipc/unixnm.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- unixnm.h 7 Feb 2009 04:31:42 -0000 1.13
+++ unixnm.h 8 Feb 2009 02:44:43 -0000 1.14
@@ -149,15 +149,23 @@
{
struct rmtunix_socket_info *info =
(struct rmtunix_socket_info *)(unix_peer(s));
+
SSI_ASSERT(rmtunix_ismagic(unix_peer(s)));
+#ifdef IPC_STALE_RMTUNIX_CACHE_FIX
+ SSI_ASSERT(atomic_read(&info->rsk_refcnt));
+
+ if (!rmtunix_ismagic(s))
+ sock_hold(s); /* RT: for _rmtunix_dealloc() */
+ info->sk = s;
+ info->rsk_cached = 1;
+#endif
spin_lock(&rmtunix_cache_listlock);
#ifdef DEBUG
++rmtunix_cache_size;
#endif
+#ifndef IPC_STALE_RMTUNIX_CACHE_FIX
info->sk = s;
-#ifdef IPC_STALE_RMTUNIX_CACHE_FIX
- info->rsk_cached = 1;
#endif
#ifdef RCU_RMTUNIX_CACHE
list_add_rcu(&info->list, &rmtunix_cache_list);
@@ -176,16 +184,13 @@
rcu_read_lock();
list_for_each_entry_rcu(info, &rmtunix_cache_list, list) {
if (info->sk == s) {
-#ifdef IPC_STALE_RMTUNIX_CACHE_FIX
LOCK_SPIN_LOCK(&info->rsk_spinlock);
if (!info->rsk_cached) {
UNLOCK_SPIN_LOCK(&info->rsk_spinlock);
break;
}
- /* rmtunix_decache_info() is our only caller */
- info->rsk_cached = 0;
+ atomic_inc(&info->rsk_refcnt);
UNLOCK_SPIN_LOCK(&info->rsk_spinlock);
-#endif
rcu_read_unlock();
return info;
}
@@ -206,33 +211,29 @@
}
static inline void
-rmtunix_decache_info(unix_socket *s)
+__rmtunix_decache_info(struct rmtunix_socket_info *info)
{
- struct rmtunix_socket_info *info =
- (struct rmtunix_socket_info *)(unix_peer(s));
- int orphan = 0;
-
-#ifndef RCU_RMTUNIX_CACHE
- spin_lock(&rmtunix_cache_listlock);
-#endif
- if (!info) {
- orphan = 1;
- info = rmtunix_cache_lookup(s);
-#ifdef IPC_STALE_RMTUNIX_CACHE_FIX
- if (!info) return;
-#endif
- }
-
- SSI_ASSERT(info);
SSI_ASSERT( rmtunix_ismagic((struct sock *)info) );
#ifdef RCU_RMTUNIX_CACHE
+ if (atomic_read(&info->rsk_refcnt) == 1)
+ might_sleep();
if (!atomic_dec_and_lock(&info->rsk_refcnt, &rmtunix_cache_listlock))
return;
-#ifdef IPC_STALE_RMTUNIX_CACHE_FIX
- /* info->rsk_cached = 0; */ /* Done in rmtunix_cache_lookup() */
-#endif
+ LOCK_SPIN_LOCK(&info->rsk_spinlock);
+ if (atomic_read(&info->rsk_refcnt)) {
+ UNLOCK_SPIN_LOCK(&info->rsk_spinlock);
+ spin_unlock(&rmtunix_cache_listlock);
+ return;
+ }
+ info->rsk_cached = 0;
+ UNLOCK_SPIN_LOCK(&info->rsk_spinlock);
list_del_rcu(&info->list);
+#ifdef DEBUG
+ --rmtunix_cache_size;
+#endif
+ spin_unlock(&rmtunix_cache_listlock);
+ call_rcu(&info->rhead, rmtunix_dealloc);
#else /* !RCU_RMTUNIX_CACHE */
#ifdef IPC_STALE_RMTUNIX_CACHE_FIX
if (!atomic_dec_and_test(&info->rsk_refcnt)) {
@@ -240,27 +241,49 @@
return;
}
info->rsk_cached = 0;
-#else
- info->sk = NULL;
#endif
+ /* SSI_XXX: Missing sock_put(info->sk) ? */
+ info->sk = NULL;
list_del(&info->list);
-#endif /* !RCU_RMTUNIX_CACHE */
#ifdef DEBUG
--rmtunix_cache_size;
#endif
spin_unlock(&rmtunix_cache_listlock);
+#endif /* !RCU_RMTUNIX_CACHE */
+}
- if (orphan) {
-#ifdef RCU_RMTUNIX_CACHE
- call_rcu(&info->rhead, rmtunix_dealloc);
-#else
+static inline void
+rmtunix_decache_info(unix_socket *s)
+{
+ struct rmtunix_socket_info *info =
+ (struct rmtunix_socket_info *)(unix_peer(s));
+ int orphan = 0;
+
+#ifndef RCU_RMTUNIX_CACHE
+ spin_lock(&rmtunix_cache_listlock);
+#endif
+ if (!info) {
+ orphan = 1;
+ info = rmtunix_cache_lookup(s);
#ifdef IPC_STALE_RMTUNIX_CACHE_FIX
- info->sk = NULL;
+ if (!info)
+ return;
+ /* SSI_XXX: expect orphans? */
+ printk(KERN_DEBUG "%s: orphan rmtunix socket info found.\n",
+ __FUNCTION__);
+#else
+ SSI_ASSERT(info);
#endif
+ }
+
+ (void) __rmtunix_decache_info(info);
+
+#ifndef RCU_RMTUNIX_CACHE
+ if (orphan) {
info->magic = 0;
kfree(info);
-#endif /* !RCU_RMTUNIX_CACHE */
}
+#endif
}
#ifndef IPC_STALE_RMTUNIX_CACHE_FIX
------------------------------------------------------------------------------
Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM)
software. With Adobe AIR, Ajax developers can use existing skills and code to
build responsive, highly engaging applications that combine the power of local
resources and data with the reach of the web. Download the Adobe AIR SDK and
Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-com