Which Process?
Patrick Schaaf
bof@bof.de
Wed, 1 Aug 2001 00:23:30 +0200
> In other words, it is unlikely that you need to worry about it.
I fully agree with this general characterization.
As the topic piqued my interest for a short time, I made a dirty hack
to measure ipt_do_table() latency. Using rdtsc() amortized over 1000
packets, I find that a simple nontaken ruleset line (simple meaning
IP checks only), takes roughly 75 clock cycles on my 500 Mhz P-III.
regards
Patrick
Here's the diff, but be careful. This is a hack, non-smp-safe,
heavily performance impacting (50% performance loss - on my
160000 pps silly flood test.) I consciously leave applying this patch,
and finding and understanding its output, as an exercize to the readers.
--- ../dl360/linux-2.4.8-pre3-vlan-pom/net/ipv4/netfilter/Config.in Fri Jul 27 08:40:17 2001
+++ ./linux-2.4.8-pre3-vlan-pom/net/ipv4/netfilter/Config.in Tue Jul 31 21:23:57 2001
@@ -14,6 +14,13 @@
fi
tristate 'IP tables support (required for filtering/masq/NAT)' CONFIG_IP_NF_IPTABLES
if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then
+ bool ' time ipt_do_table' CONFIG_NETFILTER_TIME_DO_TABLE n
+ if [ "$CONFIG_NETFILTER_TIME_DO_TABLE" = "y" ]; then
+ if [ "$CONFIG_NETFILTER_TIME_DO_TABLE_MASK" = "" ]; then
+ CONFIG_NETFILTER_TIME_DO_TABLE_MASK=1023
+ fi
+ int ' take time every N+1 packets' CONFIG_NETFILTER_TIME_DO_TABLE_MASK
+ fi
# The simple matches.
dep_tristate ' limit match support' CONFIG_IP_NF_MATCH_LIMIT $CONFIG_IP_NF_IPTABLES
--- ../dl360/linux-2.4.8-pre3-vlan-pom/net/ipv4/netfilter/ip_tables.c Tue May 15 08:29:35 2001
+++ ./linux-2.4.8-pre3-vlan-pom/net/ipv4/netfilter/ip_tables.c Tue Jul 31 21:30:05 2001
@@ -243,6 +243,38 @@
return (struct ipt_entry *)(base + offset);
}
+#if defined(CONFIG_NETFILTER_TIME_DO_TABLE)
+
+#include <asm/msr.h>
+
+static unsigned long long tdt_count = 1;
+static unsigned long long tdt_count_last = 1;
+static unsigned long long tdt_cyclesum;
+static unsigned long long tdt_cyclesum_last;
+
+static void tdt__output(void)
+{
+ unsigned long long countdiff = tdt_count - tdt_count_last;
+ unsigned long long sumdiff = tdt_cyclesum - tdt_cyclesum_last;
+
+ printk("TDT-TOTAL %Ld %Ld\n", tdt_count, tdt_cyclesum);
+ printk("TDT-RECENT %Ld %Ld\n", countdiff, sumdiff);
+ tdt_count_last = tdt_count;
+ tdt_cyclesum_last = tdt_cyclesum;
+}
+
+#if !defined(CONFIG_NETFILTER_TIME_DO_TABLE_MASK)
+#define CONFIG_NETFILTER_TIME_DO_TABLE_MASK 255
+#endif
+
+static inline void tdt_output(void)
+{
+ if ((tdt_count & CONFIG_NETFILTER_TIME_DO_TABLE_MASK) == 0)
+ tdt__output();
+}
+
+#endif
+
/* Returns one of the generic firewall policies, like NF_ACCEPT. */
unsigned int
ipt_do_table(struct sk_buff **pskb,
@@ -263,6 +295,12 @@
const char *indev, *outdev;
void *table_base;
struct ipt_entry *e, *back;
+#if defined(CONFIG_NETFILTER_TIME_DO_TABLE)
+ unsigned long long stamp_start;
+ unsigned long long stamp_end;
+
+ rdtscll(stamp_start);
+#endif
/* Initialization */
ip = (*pskb)->nh.iph;
@@ -392,6 +430,13 @@
((struct ipt_entry *)table_base)->comefrom = 0xdead57ac;
#endif
read_unlock_bh(&table->lock);
+
+#if defined(CONFIG_NETFILTER_TIME_DO_TABLE)
+ rdtscll(stamp_end);
+ tdt_count++;
+ tdt_cyclesum += (stamp_end - stamp_start);
+ tdt_output();
+#endif
#ifdef DEBUG_ALLOW_ALL
return NF_ACCEPT;