[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