[prev in list] [next in list] [prev in thread] [next in thread] 

List:       netfilter
Subject:    [PATCH] iptables vmalloc/vfree
From:       Marc Boucher <marc () mbsi ! ca>
Date:       1999-10-26 8:59:21
[Download RAW message or body]

This is a multipart MIME message.


Hi Rusty,

The enclosed patch replaces kmalloc/kfree with vmalloc/vfree in
iptables.c, to avoid problems with failing ~32k requests due to memory
fragmentation. Seems to work fine now.

Marc

1999-10-26  Marc Boucher <marc@mbsi.ca>

        * packet-filter/kernel/iptables.c: Use vmalloc/vfree instead of
        kmalloc/kfree in order to avoid spurious failures when 
        allocating large memory blocks due to fragmentation.


["netfilter-cvs-vmalloc.patch" (application/x-patch)]

--- netfilter/packet-filter/kernel/iptables.c	1999/10/25 21:33:37	1.1
+++ netfilter/packet-filter/kernel/iptables.c	1999/10/25 21:43:11
@@ -11,6 +11,7 @@
 #include <linux/skbuff.h>
 #include <linux/kmod.h>
 #include <linux/stat.h>
+#include <linux/vmalloc.h>
 #include <linux/interrupt.h>
 #include <asm/uaccess.h>
 #include <linux/netdevice.h>
@@ -713,19 +714,12 @@
 	unsigned long flags;
 
 	/* Allocate slots and new entries: alignment should be OK */
-	newinfo = kmalloc(sizeof(struct ipt_table_info)
+	newinfo = vmalloc(sizeof(struct ipt_table_info)
 			  + repl->number * sizeof(struct ipt_kern_entry)
 			  + (repl->number * NUM_SLOTS
 			     * sizeof(struct ipt_counters))
 			  + (repl->number * NUM_SLOTS
-			     * sizeof(unsigned int)),
-
-#ifdef ALWAYS_IN_INTERRUPT
-			  GFP_ATOMIC
-#else
-			  GFP_KERNEL
-#endif
-		);
+			     * sizeof(unsigned int)));
 	if (!newinfo) {
 		*error = -ENOMEM;
 		return NULL;
@@ -759,7 +753,7 @@
 	return oldinfo;
 
  bad_data:
-	kfree(newinfo);
+	vfree(newinfo);
 	return NULL;
 }
 
@@ -782,13 +776,7 @@
 		*error = -EINVAL;
 		return NULL;
 	}
-	ret = kmalloc(len,
-#ifdef ALWAYS_IN_INTERRUPT
-		      GFP_ATOMIC
-#else
-		      GFP_KERNEL
-#endif
-		);
+	ret = vmalloc(len);
 	if (!ret) {
 		duprintf("ip_tables: oom (%u).\n", len);
 		*error = -ENOMEM;
@@ -809,7 +797,7 @@
 				   len, error)) != NULL) {
 		if (copy_from_user(ret, user, len) != 0) {
 			*error = -EFAULT;
-			kfree(ret);
+			vfree(ret);
 			ret = NULL;
 		}
 	}
@@ -841,14 +829,8 @@
 	if (repl) {
 		struct ipt_counters *uout = repl->counters;
 		repl->counters
-			= kmalloc(repl->num_counters
-				  * sizeof(struct ipt_counters),
-#ifdef ALWAYS_IN_INTERRUPT
-				  GFP_ATOMIC
-#else
-				  GFP_KERNEL
-#endif
-				);
+			= vmalloc(repl->num_counters
+				  * sizeof(struct ipt_counters));
 		if (!repl->counters)
 			ret = -ENOMEM;
 		else {
@@ -865,15 +847,15 @@
 				for (i = 0; i < oldinfo->number; i++)
 					cleanup_entry(&oldinfo->table[i]);
 
-				kfree(oldinfo);
+				vfree(oldinfo);
 				/* Silent error: too late now. */
 				copy_to_user(uout, repl->counters,
 					     sizeof(struct ipt_counters)
 					     * repl->num_counters);
 			}
-			kfree(repl->counters);
+			vfree(repl->counters);
 		}
-		kfree(repl);
+		vfree(repl);
 	}
 	return ret;
 }
@@ -898,7 +880,7 @@
 					user, len, &ret);
 		if (pgetc) {
 			ret = add_counters(pgetc);
-			kfree(pgetc);
+			vfree(pgetc);
 		}
 		break;
 	}
@@ -952,7 +934,7 @@
 				    != 0)
 					ret = -EFAULT;
 			}
-			kfree(entries);
+			vfree(entries);
 		}
 		break;
 	}
@@ -1205,7 +1187,7 @@
 	for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++)
 		nf_unregister_hook(&ipt_ops[i]);
 	nf_unregister_sockopt(&ipt_sockopts);
-	kfree(ipt_table_info);
+	vfree(ipt_table_info);
 
 	IPTD_WRITE_UNLOCK_IRQ(&ipt_lock, flags);
 }


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic