]> git.hungrycats.org Git - linux/commitdiff
switch to mempools for cifs request buf and mid allocation to avoid deadlocks in...
authorSteve French <stevef@smfhome.smfdom>
Mon, 17 May 2004 16:53:34 +0000 (11:53 -0500)
committerSteve French <cifs.adm@hostme.bitkeeper.com>
Mon, 17 May 2004 16:53:34 +0000 (11:53 -0500)
fs/cifs/CHANGES
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/misc.c
fs/cifs/transport.c

index b1cb9d982eceb371bc4cdac18c7466fe6515bca5..ec0ff7e3357a637e8615938e401086a8410c18dd 100644 (file)
@@ -1,3 +1,8 @@
+Version 1.15
+------------
+Change to mempools for alloc smb request buffers and multiplex structs
+to better handle low memory problems (and potential deadlocks).
+
 Version 1.14
 ------------
 Fix incomplete listings of large directories on Samba servers when Unix
index 17458b708b2fa1a90191c5a1198168b23ee7ccf1..b017cb563224f36ed3fd104283283bc75b50923c 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/list.h>
 #include <linux/seq_file.h>
 #include <linux/vfs.h>
+#include <linux/mempool.h>
 #include "cifsfs.h"
 #include "cifspdu.h"
 #define DECLARE_GLOBALS_HERE
@@ -39,7 +40,9 @@
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
 #include <linux/mm.h>
-#define CIFS_MAGIC_NUMBER 0xFF534D42   /* the first four bytes of all SMB PDUs */
+#define CIFS_MAGIC_NUMBER 0xFF534D42   /* the first four bytes of SMB PDUs */
+/* BB when mempool_resize is added back in, we will resize pool on new mount */
+#define CIFS_MIN_RCV_POOL 11 /* enough for progress to five servers */
 
 #ifdef CIFS_QUOTA
 static struct quotactl_ops cifs_quotactl_ops;
@@ -209,9 +212,11 @@ static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd)
 }
 
 static kmem_cache_t *cifs_inode_cachep;
-kmem_cache_t *cifs_req_cachep;
-kmem_cache_t *cifs_mid_cachep;
+static kmem_cache_t *cifs_req_cachep;
+static kmem_cache_t *cifs_mid_cachep;
 kmem_cache_t *cifs_oplock_cachep;
+mempool_t *cifs_req_poolp;
+mempool_t *cifs_mid_poolp;
 
 static struct inode *
 cifs_alloc_inode(struct super_block *sb)
@@ -593,12 +598,23 @@ cifs_init_request_bufs(void)
        if (cifs_req_cachep == NULL)
                return -ENOMEM;
 
+       cifs_req_poolp = mempool_create(CIFS_MIN_RCV_POOL,
+                                       mempool_alloc_slab,
+                                       mempool_free_slab,
+                                       cifs_req_cachep);
+
+       if(cifs_req_poolp == NULL) {
+               kmem_cache_destroy(cifs_req_cachep);
+               return -ENOMEM;
+       }
+
        return 0;
 }
 
 static void
 cifs_destroy_request_bufs(void)
 {
+       mempool_destroy(cifs_req_poolp);
        if (kmem_cache_destroy(cifs_req_cachep))
                printk(KERN_WARNING
                       "cifs_destroy_request_cache: error not all structures were freed\n");
@@ -612,11 +628,22 @@ cifs_init_mids(void)
                                SLAB_HWCACHE_ALIGN, NULL, NULL);
        if (cifs_mid_cachep == NULL)
                return -ENOMEM;
+
+       cifs_mid_poolp = mempool_create(3 /* a reasonable min simultan opers */,
+                                       mempool_alloc_slab,
+                                       mempool_free_slab,
+                                       cifs_mid_cachep);
+       if(cifs_mid_poolp == NULL) {
+               kmem_cache_destroy(cifs_mid_cachep);
+               return -ENOMEM;
+       }
+
        cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs",
                                sizeof (struct oplock_q_entry), 0,
                                SLAB_HWCACHE_ALIGN, NULL, NULL);
        if (cifs_oplock_cachep == NULL) {
                kmem_cache_destroy(cifs_mid_cachep);
+               mempool_destroy(cifs_mid_poolp);
                return -ENOMEM;
        }
 
@@ -629,6 +656,7 @@ cifs_destroy_mids(void)
        if (kmem_cache_destroy(cifs_mid_cachep))
                printk(KERN_WARNING
                       "cifs_destroy_mids: error not all structures were freed\n");
+       mempool_destroy(cifs_mid_poolp);
        if (kmem_cache_destroy(cifs_oplock_cachep))
                printk(KERN_WARNING
                       "error not all oplock structures were freed\n");
index 096f48b27bc0d6dcbed33715a1fa3c8be5d9759d..bd6547993a6252180d03bd69c5ca11efb821beb3 100644 (file)
@@ -93,5 +93,5 @@ extern int    cifs_setxattr(struct dentry *, const char *, const void *,
                         size_t, int);
 extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
 extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
-#define CIFS_VERSION   "1.14"
+#define CIFS_VERSION   "1.15"
 #endif                         /* _CIFSFS_H */
index ca96ffe2c80e67f7c70d66dd8443eb27c5a90d4b..9a31ed995522c4be297ae27e942ed3d929dcf059 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/slab.h>
 #include <linux/ctype.h>
+#include <linux/mempool.h>
 #include "cifspdu.h"
 #include "cifsglob.h"
 #include "cifsproto.h"
@@ -28,7 +29,7 @@
 #include "smberr.h"
 #include "nterr.h"
 
-extern kmem_cache_t *cifs_req_cachep;
+extern mempool_t *cifs_req_poolp;
 extern struct task_struct * oplockThread;
 
 __u16 GlobalMid;               /* multiplex id - rotating counter */
@@ -153,7 +154,7 @@ cifs_buf_get(void)
    albeit slightly larger than necessary and maxbuffersize 
    defaults to this and can not be bigger */
        ret_buf =
-           (struct smb_hdr *) kmem_cache_alloc(cifs_req_cachep, SLAB_KERNEL | SLAB_NOFS);
+           (struct smb_hdr *) mempool_alloc(cifs_req_poolp, SLAB_KERNEL | SLAB_NOFS);
 
        /* clear the first few header bytes */
        if (ret_buf) {
@@ -172,7 +173,7 @@ cifs_buf_release(void *buf_to_free)
                cFYI(1, ("Null buffer passed to cifs_buf_release"));
                return;
        }
-       kmem_cache_free(cifs_req_cachep, buf_to_free);
+       mempool_free(buf_to_free,cifs_req_poolp);
 
        atomic_dec(&bufAllocCount);
        return;
index aaa78992a045d38394036e6e1204f33e525abc26..91a6baf0831d18487b89503a0c2a8eecf9b3f462 100644 (file)
 #include <linux/net.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>
+#include <linux/mempool.h>
 #include "cifspdu.h"
 #include "cifsglob.h"
 #include "cifsproto.h"
 #include "cifs_debug.h"
   
-extern kmem_cache_t *cifs_mid_cachep;
+extern mempool_t *cifs_mid_poolp;
 extern kmem_cache_t *cifs_oplock_cachep;
 
 struct mid_q_entry *
@@ -47,8 +48,7 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
                return NULL;
        }
        
-       temp = (struct mid_q_entry *) kmem_cache_alloc(cifs_mid_cachep,
-                                                      SLAB_KERNEL);
+       temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp,SLAB_KERNEL | SLAB_NOFS);
        if (temp == NULL)
                return temp;
        else {
@@ -79,7 +79,7 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
        atomic_dec(&midCount);
        spin_unlock(&GlobalMid_Lock);
        cifs_buf_release(midEntry->resp_buf);
-       kmem_cache_free(cifs_mid_cachep, midEntry);
+       mempool_free(midEntry, cifs_mid_poolp);
 }
 
 struct oplock_q_entry *