Re: Route cache performance under stress

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



 > David S. Miller writes:
 > Next, we should put similar metrics into fib_hash.c

 A starting point...

 Kernel hack enclosed and companion app from:
 ftp://robur.slu.se/pub/Linux/net-development/fibstat
 
 Just some hash metrics yet. Output below is from our DoS tests:

lookup_total   == hash lookup/sec
zone_search    == zones search/sec
chain_search   == chain search/sec

lookup_total  zone_search chain_search
           0            0            0
           0            0            0
           0            0            0
      475084      4513198      2454249
      861704      8186188      4450394
      867935      8245366      4480320
      863319      8201514      4458924
      864056      8208532      4463344
      863788      8205986      4461238
      861772      8186834      4449507


--- include/net/ip_fib.h.030617	2003-06-17 15:03:57.000000000 +0200
+++ include/net/ip_fib.h	2003-06-17 16:07:00.000000000 +0200
@@ -135,6 +135,21 @@
 	unsigned char	tb_data[0];
 };
 
+struct fib_stat 
+{
+        unsigned int lookup_total;
+        unsigned int zone_search;
+        unsigned int chain_search;
+};
+
+extern struct fib_stat *fib_stat;
+#define FIB_STAT_INC(field)                                          \
+                (per_cpu_ptr(fib_stat, smp_processor_id())->field++)
+
+
+extern int __init fib_stat_init(void);
+
+
 #ifndef CONFIG_IP_MULTIPLE_TABLES
 
 extern struct fib_table *ip_fib_local_table;
--- net/ipv4/fib_hash.c.030617	2003-06-15 23:02:21.000000000 +0200
+++ net/ipv4/fib_hash.c	2003-06-17 16:01:45.000000000 +0200
@@ -13,6 +13,11 @@
  *		modify it under the terms of the GNU General Public License
  *		as published by the Free Software Foundation; either version
  *		2 of the License, or (at your option) any later version.
+ *
+ *
+ * Fixes:
+ * Robert Olsson		:	Added statistics
+ *
  */
 
 #include <linux/config.h>
@@ -107,6 +112,10 @@
 	struct fn_zone	*fn_zone_list;
 };
 
+
+struct fib_stat *fib_stat;
+
+
 static __inline__ fn_hash_idx_t fn_hash(fn_key_t key, struct fn_zone *fz)
 {
 	u32 h = ntohl(key.datum)>>(32 - fz->fz_order);
@@ -307,12 +316,19 @@
 	struct fn_zone *fz;
 	struct fn_hash *t = (struct fn_hash*)tb->tb_data;
 
+	FIB_STAT_INC(lookup_total);
+
 	read_lock(&fib_hash_lock);
 	for (fz = t->fn_zone_list; fz; fz = fz->fz_next) {
 		struct fib_node *f;
 		fn_key_t k = fz_key(flp->fl4_dst, fz);
 
+		FIB_STAT_INC(zone_search);
+
 		for (f = fz_chain(k, fz); f; f = f->fn_next) {
+
+			FIB_STAT_INC(chain_search);
+
 			if (!fn_key_eq(k, f->fn_key)) {
 				if (fn_key_leq(k, f->fn_key))
 					break;
@@ -1108,6 +1124,54 @@
 	.release	= ip_seq_release,
 };
 
+static int fib_stat_get_info(char *buffer, char **start, off_t offset, int length)
+{
+	int i;
+	int len = 0;
+
+	for (i = 0; i < NR_CPUS; i++) {
+		if (!cpu_possible(i))
+			continue;
+		len += sprintf(buffer+len, "%08x %08x %08x \n",
+			       per_cpu_ptr(fib_stat, i)->lookup_total,
+			       per_cpu_ptr(fib_stat, i)->zone_search,
+			       per_cpu_ptr(fib_stat, i)->chain_search
+
+			);
+	}
+	len -= offset;
+
+	if (len > length)
+		len = length;
+	if (len < 0)
+		len = 0;
+
+	*start = buffer + offset;
+  	return len;
+}
+
+int __init fib_stat_init(void)
+{
+	int i, rc = 0;
+
+	fib_stat = kmalloc_percpu(sizeof (struct fib_stat),
+				  GFP_KERNEL);
+	if (!fib_stat) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < NR_CPUS; i++) {
+		if (cpu_possible(i)) {
+			memset(per_cpu_ptr(fib_stat, i), 0,
+			       sizeof (struct fib_stat));
+		}
+	}
+	
+ out:
+	return rc;
+}
+
 int __init fib_proc_init(void)
 {
 	struct proc_dir_entry *p;
@@ -1116,13 +1180,27 @@
 	p = create_proc_entry("route", S_IRUGO, proc_net);
 	if (p)
 		p->proc_fops = &fib_seq_fops;
-	else
+	else {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+
+
+        p = proc_net_create ("fib_stat", 0, fib_stat_get_info);
+
+	if (!p) {
 		rc = -ENOMEM;
+		remove_proc_entry("route", proc_net);
+	}
+
+ out:
 	return rc;
 }
 
 void __init fib_proc_exit(void)
 {
 	remove_proc_entry("route", proc_net);
+	remove_proc_entry("fib_stat", proc_net);
 }
 #endif /* CONFIG_PROC_FS */
--- net/ipv4/route.c.030617	2003-06-16 16:56:34.000000000 +0200
+++ net/ipv4/route.c	2003-06-17 16:02:41.000000000 +0200
@@ -2754,7 +2754,8 @@
 	rt_cache_stat = kmalloc_percpu(sizeof (struct rt_cache_stat),
 					GFP_KERNEL);
 	if (!rt_cache_stat) 
-		goto out_enomem1;
+		goto out_enomem0;
+
 	for (i = 0; i < NR_CPUS; i++) {
 		if (cpu_possible(i)) {
 			memset(per_cpu_ptr(rt_cache_stat, i), 0,
@@ -2765,6 +2766,9 @@
 	devinet_init();
 	ip_fib_init();
 
+	if(fib_stat_init()) 
+		goto out_enomem1;
+
 	init_timer(&rt_flush_timer);
 	rt_flush_timer.function = rt_run_flush;
 	init_timer(&rt_periodic_timer);
@@ -2785,7 +2789,7 @@
 
 #ifdef CONFIG_PROC_FS
 	if (rt_cache_proc_init())
-		goto out_enomem;
+		goto out_enomem2;
 	proc_net_create ("rt_cache_stat", 0, rt_cache_stat_get_info);
 #ifdef CONFIG_NET_CLS_ROUTE
 	create_proc_read_entry("net/rt_acct", 0, 0, ip_rt_acct_read, NULL);
@@ -2795,9 +2799,12 @@
 	xfrm4_init();
 out:
 	return rc;
-out_enomem:
-	kfree_percpu(rt_cache_stat);
+
+out_enomem2:
+	kfree_percpu(fib_stat);
 out_enomem1:
+	kfree_percpu(rt_cache_stat);
+out_enomem0:
 	rc = -ENOMEM;
 	goto out;
 }


Cheers.
					--ro
-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux