[SSI] openssi/kernel/cluster/ssi/util ssidev.c,1.30,1.31

Roger Tsang <[email protected]> Fri, 05 Mar 2010 06:14:14 +0000
Newsgroups gmane.linux.cluster.ssic.cvs
Message-ID <[email protected]>
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv5560/kernel/cluster/ssi/util

Modified Files:
      Tag: OPENSSI-FC
	ssidev.c 
Log Message:
SSIDEV (#ifdef SSIDEV_POLL_CLI_HASH_TABLE):
- Convert ssidev_poll_cli_list to hashed single-linked list to handle
  large number of entries.

 cluster/ssi/util/ssidev.c    |   57 ++++++++++++++++++++++++++++++++++-
 include/cluster/ssi/ssidev.h |    4 ++
 include/linux/config.h       |    4 ++
 3 files changed, 64 insertions(+), 1 deletion(-)


Index: ssidev.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/ssidev.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- ssidev.c	5 Mar 2010 05:44:39 -0000	1.30
+++ ssidev.c	5 Mar 2010 06:14:12 -0000	1.31
@@ -31,6 +31,9 @@
 #include <linux/smp_lock.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/dpvproc.h>
+#ifdef SSIDEV_POLL_CLI_HASH_TABLE
+#include <linux/hash.h>
+#endif
 #include <linux/module.h>
 #include <linux/mount.h>
 
@@ -97,7 +100,12 @@
 
 static DECLARE_WAIT_QUEUE_HEAD (ssidev_wait_queue);
 
+#ifdef SSIDEV_POLL_CLI_HASH_TABLE
+static unsigned int ssidev_pc_hash_len, ssidev_pc_hash_bits;
+static struct hlist_head *ssidev_pc_list; /* poll client list */
+#else
 static LIST_HEAD(ssidev_poll_cli_list);
+#endif
 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(ssidev_poll_cli_spinlock);
 
 static clusternode_t	 ssidev_mount_sem_node = 0;
@@ -982,13 +990,28 @@
 }
 #endif /* !RCU_SSIDEV_POLL_CLI_LIST */
 
+#ifdef SSIDEV_POLL_CLI_HASH_TABLE
+static inline unsigned long ssidev_pc_hash(ssidev_poll_cli_t *pcp)
+{
+	return hash_ptr((void *)pcp, ssidev_pc_hash_bits);
+}
+#endif /* SSIDEV_POLL_CLI_HASH_TABLE */
+
 void ssidev_poll_wake_cli(caddr_t cpcp)
 {
 	ssidev_poll_cli_t *pcp;
+#ifdef SSIDEV_POLL_CLI_HASH_TABLE
+	struct hlist_node *pos;
+	unsigned long hash = ssidev_pc_hash((ssidev_poll_cli_t *)cpcp);
+#endif
 
 #ifdef RCU_SSIDEV_POLL_CLI_LIST
 	rcu_read_lock();
+#ifdef SSIDEV_POLL_CLI_HASH_TABLE
+	hlist_for_each_entry_rcu(pcp, pos, &ssidev_pc_list[hash], pc_list) {
+#else
 	list_for_each_entry_rcu(pcp, &ssidev_poll_cli_list, pc_list) {
+#endif
 		if (pcp == (ssidev_poll_cli_t *)cpcp) {
 			if (!test_and_set_bit(pc_wakeup, &pcp->pc_state))
 				wake_up_process(pcp->pc_proc);
@@ -1110,12 +1133,32 @@
 
 static void ssidev_poll_cli_init(void)
 {
+#ifdef SSIDEV_POLL_CLI_HASH_TABLE
+	int idx;
+
+	ssidev_pc_list = (typeof(ssidev_pc_list)) __get_free_page(GFP_KERNEL);
+	if (!ssidev_pc_list)
+		panic("%s: no memory for ssidev_pc_list\n", __FUNCTION__);
+
+	ssidev_pc_hash_len = PAGE_SIZE / sizeof(*ssidev_pc_list);
+	ssidev_pc_hash_bits = 0;
+	for (idx = ssidev_pc_hash_len; idx > 1; idx >>= 1)
+		ssidev_pc_hash_bits++;
+#ifdef DEBUG
+	printk(KERN_DEBUG "%s: ssidev_pc_hash_len=%lu, ssidev_pc_hash_bits=%u\n",
+		__FUNCTION__, ssidev_pc_hash_len, ssidev_pc_hash_bits);
+#endif
+
+	for (idx = 0; idx < ssidev_pc_hash_len; ++idx)
+		INIT_HLIST_HEAD(&ssidev_pc_list[idx]);
+#endif /* SSIDEV_POLL_CLI_HASH_TABLE */
+
 	ssidev_poll_cli_cachep = kmem_cache_create("ssidev_poll_cli",
 				sizeof(ssidev_poll_cli_t), 0,
 				SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
 				ssidev_poll_cli_ctor, NULL);
 }
-#endif
+#endif /* SSIDEV_POLL_CLI_KMEM_CACHE */
 
 ssidev_poll_cli_t *ssidev_poll_cli_alloc(unsigned int events,
 					 int (*retfunc)(ssidev_pollfd_t *))
@@ -1145,12 +1188,20 @@
 #endif
 	memset(pcp->pc_node, 0, sizeof(pcp->pc_node));
 #endif /* !SSIDEV_POLL_CLI_KMEM_CACHE */
+#ifdef SSIDEV_POLL_CLI_HASH_TABLE
+	INIT_HLIST_NODE(&pcp->pc_list);
+#else
 	INIT_LIST_HEAD(&pcp->pc_list);
+#endif
 	pcp->pc_events = events;
 	pcp->pc_retfunc = retfunc;
 	spin_lock(&ssidev_poll_cli_spinlock);
 #ifdef RCU_SSIDEV_POLL_CLI_LIST
+#ifdef SSIDEV_POLL_CLI_HASH_TABLE
+	hlist_add_head_rcu(&pcp->pc_list, &ssidev_pc_list[ssidev_pc_hash(pcp)]);
+#else
 	list_add_rcu(&pcp->pc_list, &ssidev_poll_cli_list);
+#endif
 #else
 	list_add(&pcp->pc_list, &ssidev_poll_cli_list);
 #endif
@@ -1171,7 +1222,11 @@
 		return;
 	spin_lock(&ssidev_poll_cli_spinlock);
 #ifdef RCU_SSIDEV_POLL_CLI_LIST
+#ifdef SSIDEV_POLL_CLI_HASH_TABLE
+	hlist_del_rcu(&pcp->pc_list);
+#else
 	list_del_rcu(&pcp->pc_list);
+#endif
 #else
 	list_del(&pcp->pc_list);
 #endif


------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev