* [PATCH] inet: cleanup of local_port_range
@ 2008-10-08 21:13 Eric Dumazet
2008-10-08 21:18 ` David Miller
0 siblings, 1 reply; 2+ messages in thread
From: Eric Dumazet @ 2008-10-08 21:13 UTC (permalink / raw)
To: David S. Miller, Linux Netdev List
[-- Attachment #1: Type: text/plain, Size: 605 bytes --]
I noticed sysctl_local_port_range[] and its associated seqlock
sysctl_local_port_range_lock were on separate cache lines.
Moreover, sysctl_local_port_range[] was close to unrelated
variables, highly modified, leading to cache misses.
Moving these two variables in a structure can help data
locality and moving this structure to read_mostly section
helps sharing of this data among cpus.
Cleanup of extern declarations (moved in include file where
they belong), and use of inet_get_local_port_range()
accessor instead of direct access to ports values.
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
[-- Attachment #2: local_ports.patch --]
[-- Type: text/plain, Size: 4152 bytes --]
diff --git a/include/net/ip.h b/include/net/ip.h
index d678ea3..2a77dde 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -178,6 +178,10 @@ extern unsigned long snmp_fold_field(void *mib[], int offt);
extern int snmp_mib_init(void *ptr[2], size_t mibsize);
extern void snmp_mib_free(void *ptr[2]);
+extern struct local_ports {
+ seqlock_t lock;
+ int range[2];
+ } sysctl_local_ports;
extern void inet_get_local_port_range(int *low, int *high);
extern int sysctl_ip_default_ttl;
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 21fcc5a..bd1278a 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -30,20 +30,22 @@ EXPORT_SYMBOL(inet_csk_timer_bug_msg);
#endif
/*
- * This array holds the first and last local port number.
+ * This struct holds the first and last local port number.
*/
-int sysctl_local_port_range[2] = { 32768, 61000 };
-DEFINE_SEQLOCK(sysctl_port_range_lock);
+struct local_ports sysctl_local_ports __read_mostly = {
+ .lock = SEQLOCK_UNLOCKED,
+ .range = { 32768, 61000 },
+};
void inet_get_local_port_range(int *low, int *high)
{
unsigned seq;
do {
- seq = read_seqbegin(&sysctl_port_range_lock);
+ seq = read_seqbegin(&sysctl_local_ports.lock);
- *low = sysctl_local_port_range[0];
- *high = sysctl_local_port_range[1];
- } while (read_seqretry(&sysctl_port_range_lock, seq));
+ *low = sysctl_local_ports.range[0];
+ *high = sysctl_local_ports.range[1];
+ } while (read_seqretry(&sysctl_local_ports.lock, seq));
}
EXPORT_SYMBOL(inet_get_local_port_range);
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index e0689fd..276d047 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -26,16 +26,13 @@ static int tcp_retr1_max = 255;
static int ip_local_port_range_min[] = { 1, 1 };
static int ip_local_port_range_max[] = { 65535, 65535 };
-extern seqlock_t sysctl_port_range_lock;
-extern int sysctl_local_port_range[2];
-
/* Update system visible IP port range */
static void set_local_port_range(int range[2])
{
- write_seqlock(&sysctl_port_range_lock);
- sysctl_local_port_range[0] = range[0];
- sysctl_local_port_range[1] = range[1];
- write_sequnlock(&sysctl_port_range_lock);
+ write_seqlock(&sysctl_local_ports.lock);
+ sysctl_local_ports.range[0] = range[0];
+ sysctl_local_ports.range[1] = range[1];
+ write_sequnlock(&sysctl_local_ports.lock);
}
/* Validate changes from /proc interface. */
@@ -44,8 +41,7 @@ static int ipv4_local_port_range(ctl_table *table, int write, struct file *filp,
size_t *lenp, loff_t *ppos)
{
int ret;
- int range[2] = { sysctl_local_port_range[0],
- sysctl_local_port_range[1] };
+ int range[2];
ctl_table tmp = {
.data = &range,
.maxlen = sizeof(range),
@@ -54,6 +50,7 @@ static int ipv4_local_port_range(ctl_table *table, int write, struct file *filp,
.extra2 = &ip_local_port_range_max,
};
+ inet_get_local_port_range(range, range + 1);
ret = proc_dointvec_minmax(&tmp, write, filp, buffer, lenp, ppos);
if (write && ret == 0) {
@@ -73,8 +70,7 @@ static int ipv4_sysctl_local_port_range(ctl_table *table, int __user *name,
void __user *newval, size_t newlen)
{
int ret;
- int range[2] = { sysctl_local_port_range[0],
- sysctl_local_port_range[1] };
+ int range[2];
ctl_table tmp = {
.data = &range,
.maxlen = sizeof(range),
@@ -83,6 +79,7 @@ static int ipv4_sysctl_local_port_range(ctl_table *table, int __user *name,
.extra2 = &ip_local_port_range_max,
};
+ inet_get_local_port_range(range, range + 1);
ret = sysctl_intvec(&tmp, name, nlen, oldval, oldlenp, newval, newlen);
if (ret == 0 && newval && newlen) {
if (range[1] < range[0])
@@ -396,8 +393,8 @@ static struct ctl_table ipv4_table[] = {
{
.ctl_name = NET_IPV4_LOCAL_PORT_RANGE,
.procname = "ip_local_port_range",
- .data = &sysctl_local_port_range,
- .maxlen = sizeof(sysctl_local_port_range),
+ .data = &sysctl_local_ports.range,
+ .maxlen = sizeof(sysctl_local_ports.range),
.mode = 0644,
.proc_handler = &ipv4_local_port_range,
.strategy = &ipv4_sysctl_local_port_range,
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] inet: cleanup of local_port_range
2008-10-08 21:13 [PATCH] inet: cleanup of local_port_range Eric Dumazet
@ 2008-10-08 21:18 ` David Miller
0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2008-10-08 21:18 UTC (permalink / raw)
To: dada1; +Cc: netdev
From: Eric Dumazet <dada1@cosmosbay.com>
Date: Wed, 08 Oct 2008 23:13:58 +0200
> I noticed sysctl_local_port_range[] and its associated seqlock
> sysctl_local_port_range_lock were on separate cache lines.
> Moreover, sysctl_local_port_range[] was close to unrelated
> variables, highly modified, leading to cache misses.
>
> Moving these two variables in a structure can help data
> locality and moving this structure to read_mostly section
> helps sharing of this data among cpus.
>
> Cleanup of extern declarations (moved in include file where
> they belong), and use of inet_get_local_port_range()
> accessor instead of direct access to ports values.
>
> Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Applied, thanks Eric.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2008-10-08 21:18 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-08 21:13 [PATCH] inet: cleanup of local_port_range Eric Dumazet
2008-10-08 21:18 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).