From a0a95c919ca2119f0bffaf00867f682f562806f4 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 23 Nov 2007 15:11:36 -0500 Subject: [PATCH] Import 2.0.33pre2 --- include/linux/ax25.h | 1 - include/linux/netrom.h | 1 - include/net/route.h | 11 +++++++++++ net/ipv4/ip_forward.c | 7 ++++++- net/ipv4/route.c | 3 ++- net/ipv4/udp.c | 3 +++ net/unix/garbage.c | 27 +++++++++++++++++++++------ 7 files changed, 43 insertions(+), 10 deletions(-) diff --git a/include/linux/ax25.h b/include/linux/ax25.h index 68871b23f030..41baa0b22f88 100644 --- a/include/linux/ax25.h +++ b/include/linux/ax25.h @@ -6,7 +6,6 @@ #ifndef AX25_KERNEL_H #define AX25_KERNEL_H -#define PF_AX25 AF_AX25 #define AX25_MTU 256 #define AX25_MAX_DIGIS 6 /* This is wrong, should be 8 */ diff --git a/include/linux/netrom.h b/include/linux/netrom.h index abef3c85d3e5..69df9fe91dbc 100644 --- a/include/linux/netrom.h +++ b/include/linux/netrom.h @@ -7,7 +7,6 @@ #ifndef NETROM_KERNEL_H #define NETROM_KERNEL_H -#define PF_NETROM AF_NETROM #define NETROM_MTU 236 #define NETROM_T1 1 diff --git a/include/net/route.h b/include/net/route.h index 3af796f9670e..dc067900a4ee 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -14,6 +14,11 @@ * Alan Cox : Support for TCP parameters. * Alexey Kuznetsov: Major changes for new routing code. * Elliot Poger : Added support for SO_BINDTODEVICE. + * Wolfgang Walter, + * Daniel Ryde, + * Ingo Molinar : fixed bug in ip_rt_put introduced + * by SO_BINDTODEVICE support causing + * a memory leak * * FIXME: * Make atomic ops more generic and hide them in asm/... @@ -98,6 +103,7 @@ extern void ip_rt_run_bh(void); extern atomic_t ip_rt_lock; extern unsigned ip_rt_bh_mask; extern struct rtable *ip_rt_hash_table[RT_HASH_DIVISOR]; +extern void rt_free(struct rtable * rt); extern __inline__ void ip_rt_fast_lock(void) { @@ -127,6 +133,11 @@ extern __inline__ void ip_rt_put(struct rtable * rt) { if (rt) atomic_dec(&rt->rt_refcnt); + + /* If this rtable entry is not in the cache, we'd better free it once the + * refcnt goes to zero, because nobody else will... */ + if ( rt && (rt->rt_flags & RTF_NOTCACHED) && (!rt->rt_refcnt) ) + rt_free(rt); } #else ; diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index d9e44c9023f5..564ff9246881 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c @@ -16,6 +16,7 @@ * use output device for accounting. * Jos Vos : Call forward firewall after routing * (always use output device). + * Philip Gladstone: Add some missing ip_rt_put() */ #include @@ -113,7 +114,7 @@ int ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, struct device *dev2; /* Output device */ struct iphdr *iph; /* Our header */ struct sk_buff *skb2; /* Output packet */ - struct rtable *rt; /* Route we use */ + struct rtable *rt = NULL; /* Route we use */ unsigned char *ptr; /* Data pointer */ unsigned long raddr; /* Router IP address */ struct options * opt = (struct options*)skb->proto_priv; @@ -301,6 +302,8 @@ int ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev); /* fall thru */ default: + if (rt) + ip_rt_put(rt); return -1; } @@ -454,6 +457,8 @@ int ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, icmp_send(skb2, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev); if (skb != skb2) kfree_skb(skb2,FREE_WRITE); + if (rt) + ip_rt_put(rt); return -1; } #endif diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 79661fa76866..3104fb0ace67 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -45,6 +45,7 @@ * Elliot Poger : Added support for SO_BINDTODEVICE. * Andi Kleen : Don't send multicast addresses to * kerneld. + * Wolfgang Walter : make rt_free() non-static * * Juan Jose Ciarlante : Added ip_rt_dev * This program is free software; you can redistribute it and/or @@ -891,7 +892,7 @@ done: } -static void rt_free(struct rtable * rt) +void rt_free(struct rtable * rt) { unsigned long flags; diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 1f5aff88a8ca..fc8baa695b59 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -55,6 +55,7 @@ * Elliot Poger : Added support for SO_BINDTODEVICE. * Willy Konynenberg : Transparent proxy adapted to new * socket hash code. + * Philip Gladstone: Added missing ip_rt_put * * * This program is free software; you can redistribute it and/or @@ -874,6 +875,8 @@ int udp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len) sk->daddr = usin->sin_addr.s_addr; sk->dummy_th.dest = usin->sin_port; sk->state = TCP_ESTABLISHED; + if (sk->ip_route_cache) + ip_rt_put(sk->ip_route_cache); sk->ip_route_cache = rt; return(0); } diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 3b7e114dda3d..46ead621978a 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -5,6 +5,16 @@ * Copyright (C) Barak A. Pearlmutter. * Released under the GPL version 2 or later. * + * 12/3/97 -- Flood + * Internal stack is only allocated one page. On systems with NR_FILE + * > 1024, this makes it quite easy for a user-space program to open + * a large number of AF_UNIX domain sockets, causing the garbage + * collection routines to run up against the wall (and panic). + * Changed the MAX_STACK to be associated to the system-wide open file + * maximum, and use vmalloc() instead of get_free_page() [as more than + * one page may be necessary]. As noted below, this should ideally be + * done with a linked list. + * * Chopped about by Alan Cox 22/3/96 to make it fit the AF_UNIX socket problem. * If it doesn't work blame me, it worked when Barak sent it. * @@ -59,10 +69,9 @@ /* Internal data structures and random procedures: */ -#define MAX_STACK 1000 /* Maximum depth of tree (about 1 page) */ static unix_socket **stack; /* stack of objects to mark */ static int in_stack = 0; /* first free entry in stack */ - +static int max_stack; /* Calculated in unix_gc() */ extern inline unix_socket *unix_get_socket(struct file *filp) { @@ -110,7 +119,7 @@ void unix_notinflight(struct file *fp) extern inline void push_stack(unix_socket *x) { - if (in_stack == MAX_STACK) + if (in_stack == max_stack) panic("can't push onto full stack"); stack[in_stack++] = x; } @@ -151,8 +160,14 @@ void unix_gc(void) if(in_unix_gc) return; in_unix_gc=1; - - stack=(unix_socket **)get_free_page(GFP_KERNEL); + + max_stack = max_files; + + stack=(unix_socket **)vmalloc(max_stack * sizeof(unix_socket **)); + if (!stack) { + in_unix_gc=0; + return; + } /* * Assume everything is now unmarked @@ -276,5 +291,5 @@ tail: in_unix_gc=0; - free_page((long)stack); + vfree(stack); } -- 2.39.5