[SSI] openssi/kernel/cluster/ssi/cfs cfsproc.c,1.34,1.35

Roger Tsang <[email protected]>
Newsgroups gmane.linux.cluster.ssic.cvs
Message-ID <[email protected]>
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs
In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv9776/kernel/cluster/ssi/cfs

Modified Files:
      Tag: OPENSSI-FC
	cfsproc.c 
Log Message:
CFS (#ifdef CFS_PAGES_CACHE):
- Use bitmap to represent set of cfs_pagevec's in cfs_pagevec_pool.
- Regression:
  - Stale page pointers in recycled cfs_pagevec slab when cfs_pagevec_pool is full.


Index: cfsproc.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/cfsproc.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -d -r1.34 -r1.35
--- cfsproc.c	27 Oct 2009 03:18:29 -0000	1.34
+++ cfsproc.c	18 Nov 2009 06:15:56 -0000	1.35
@@ -440,12 +440,15 @@
 #ifdef ICS_OOL_STRUCT_PAGES
 #ifdef CFS_PAGES_CACHE
 /* Manage the number of cfs_pagevec's in cache.
- * kmem_cache dtor is deprecated so we have to manage ourselves.
+ * kmem_cache destructor is deprecated so we have to manage ourselves.
  */
-static struct page **cfs_pagevec_pool[64];
-static DEFINE_SPINLOCK(cfs_pagevec_pool_lock);
+#define MAX_CFS_PAGEVECS (64)
+static __cacheline_aligned_in_smp DEFINE_SPINLOCK(cfs_pagevec_lock);
+static DECLARE_BITMAP(cfs_pagevec_bitmap, MAX_CFS_PAGEVECS);
+static struct page **cfs_pagevec_pool[MAX_CFS_PAGEVECS];
 
 static kmem_cache_t *cfs_pagevec_cachep;
+#define CFS_PAGEVEC_MAXLEN ((CFS_MAX_FILE_IO_SIZE + PAGE_SIZE - 1) >> PAGE_SHIFT)
 
 static void
 cfs_pagevec_ctor(void * foo, kmem_cache_t * cachep, unsigned long flags)
@@ -459,18 +462,19 @@
 void
 cfs_pagevec_init(void)
 {
-	size_t max_len = (CFS_MAX_FILE_IO_SIZE + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	int i;
 
 	cfs_pagevec_cachep = kmem_cache_create("cfs_pagevec",
-				max_len * sizeof(struct page *), 0,
+				CFS_PAGEVEC_MAXLEN * sizeof(struct page *), 0,
 				SLAB_PANIC, cfs_pagevec_ctor, NULL);
 
 	dprintk("cfs_pagevec pool max entries: %u (%u pages)\n",
-		ARRAY_SIZE(cfs_pagevec_pool),
-		ARRAY_SIZE(cfs_pagevec_pool) * max_len);
-	for (i = 0; i < ARRAY_SIZE(cfs_pagevec_pool); i++)
+		MAX_CFS_PAGEVECS,
+		MAX_CFS_PAGEVECS * (unsigned)CFS_PAGEVEC_MAXLEN);
+
+	for (i = 0; i < MAX_CFS_PAGEVECS; i++)
 		cfs_pagevec_pool[i] = NULL;
+	bitmap_zero(cfs_pagevec_bitmap, MAX_CFS_PAGEVECS);
 }
 #endif /* CFS_PAGES_CACHE */
 
@@ -478,26 +482,19 @@
 cfs_pagevec_alloc(unsigned int len)
 {
 	struct page **pages = NULL;
-	int i, max_len;
+	int i;
 
 #ifdef CFS_PAGES_CACHE
-	rcu_read_lock();
-	for (i = 0; i < ARRAY_SIZE(cfs_pagevec_pool); i++) {
-		if (cfs_pagevec_pool[i]) {
-			spin_lock(&cfs_pagevec_pool_lock);
-			if (!cfs_pagevec_pool[i]) {
-				spin_unlock(&cfs_pagevec_pool_lock);
-				continue;
-			}
-			/* Re-use the pagevec */
-			pages = cfs_pagevec_pool[i];
-			cfs_pagevec_pool[i] = NULL;
-			spin_unlock(&cfs_pagevec_pool_lock);
-			break;
-		}
+	spin_lock(&cfs_pagevec_lock);
+
+	i = find_first_bit(cfs_pagevec_bitmap, MAX_CFS_PAGEVECS);
+	if (i < MAX_CFS_PAGEVECS) {
+		__clear_bit(i, cfs_pagevec_bitmap);
+		pages = cfs_pagevec_pool[i];
 	}
-	rcu_read_unlock();
-	if (!pages)
+	spin_unlock(&cfs_pagevec_lock);
+
+	if (i >= MAX_CFS_PAGEVECS)
 		pages = kmem_cache_alloc(cfs_pagevec_cachep, GFP_KERNEL|__GFP_NOFAIL);
 #else
 	unsigned int array_size;
@@ -506,8 +503,7 @@
 	pages = kmalloc_nofail(array_size);
 #endif /* !CFS_PAGES_CACHE */
 
-	max_len = (CFS_MAX_FILE_IO_SIZE + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	BUG_ON(len > max_len);
+	BUG_ON(len > CFS_PAGEVEC_MAXLEN);
 
 	/* Dynamically allocate pages for the pagevec */
 	i = len - 1;
@@ -524,32 +520,24 @@
 cfs_pagevec_free(struct page ** pages)
 {
 #ifdef CFS_PAGES_CACHE
-	int i, max_len;
+	int i;
 
-	rcu_read_lock();
-	for (i = 0; i < ARRAY_SIZE(cfs_pagevec_pool); i++) {
-		if (!cfs_pagevec_pool[i]) {
-			spin_lock(&cfs_pagevec_pool_lock);
-			if (cfs_pagevec_pool[i]) {
-				spin_unlock(&cfs_pagevec_pool_lock);
-				continue;
-			}
-			/* Insert pagevec into pool for re-use */
-			cfs_pagevec_pool[i] = pages;
-			pages = NULL;
-			spin_unlock(&cfs_pagevec_pool_lock);
-			break;
-		}
+	spin_lock(&cfs_pagevec_lock);
+
+	i = find_first_zero_bit(cfs_pagevec_bitmap, MAX_CFS_PAGEVECS);
+	if (i < MAX_CFS_PAGEVECS) {
+		__set_bit(i, cfs_pagevec_bitmap);
+		cfs_pagevec_pool[i] = pages;
 	}
-	rcu_read_unlock();
-	if (pages) {
-		max_len = (CFS_MAX_FILE_IO_SIZE + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	spin_unlock(&cfs_pagevec_lock);
 
+	if (i >= MAX_CFS_PAGEVECS) {
 		/* Do the kmem_cache destructor */
-		for (i = 0; i < max_len; i++) {
+		for (i = 0; i < CFS_PAGEVEC_MAXLEN; i++) {
 			if (!pages[i])
 				break;
 			__free_page(pages[i]);
+			pages[i] = NULL;
 		}
 
 		kmem_cache_free(cfs_pagevec_cachep, (void *)pages);


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.