lkml.org 
[lkml]   [2003]   [Mar]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
SubjectRe: 2.4.20-ac2 Memory Leak?
From
Date
On Wed, 2003-03-19 at 00:17, Gregory Stark wrote:
> My router box has a problem, it seems to be running out of memory. Programs
> that worked fine earlier are now swapping like crazy.
>
> What confuses me is that if I add up all the RSS of the processes I get 5.9M,
> a number drastically lower than the available RAM on the machine (24M) and
> drastically lower than the amount of RAM "free" says is taken (22M).
>
> It seems something in kernel space has taken a ton of memory out of play?
> Or is my diagnosis wrong?

2.4.20 changed the linked list handling and ip_conntrack relied on the
old way. I've attached a patch that removes this assumption from
ip_conntrack.

This can be the source of your problems, connections can get very long
timeouts and stay in ip_conntrack.

--
/Martin

Never argue with an idiot. They drag you down to their level, then beat you with experience.
diff -urN --exclude-from=diff.exclude linux-2.4.20-base/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.4.20-del/include/linux/netfilter_ipv4/ip_conntrack.h
--- linux-2.4.20-base/include/linux/netfilter_ipv4/ip_conntrack.h Fri Nov 29 00:53:15 2002
+++ linux-2.4.20-del/include/linux/netfilter_ipv4/ip_conntrack.h Fri Feb 21 17:01:38 2003
@@ -6,6 +6,7 @@

#include <linux/config.h>
#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
+#include <linux/bitops.h>
#include <asm/atomic.h>

enum ip_conntrack_info
@@ -41,6 +42,10 @@
/* Conntrack should never be early-expired. */
IPS_ASSURED_BIT = 2,
IPS_ASSURED = (1 << IPS_ASSURED_BIT),
+
+ /* Connection is confirmed: originating packet has left box */
+ IPS_CONFIRMED_BIT = 3,
+ IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
};

#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
@@ -159,7 +164,7 @@
struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];

/* Have we seen traffic both ways yet? (bitset) */
- volatile unsigned long status;
+ unsigned long status;

/* Timer function; drops refcnt when it goes off. */
struct timer_list timeout;
@@ -254,7 +259,7 @@
/* It's confirmed if it is, or has been in the hash table. */
static inline int is_confirmed(struct ip_conntrack *ct)
{
- return ct->tuplehash[IP_CT_DIR_ORIGINAL].list.next != NULL;
+ return test_bit(IPS_CONFIRMED_BIT, &ct->status);
}

extern unsigned int ip_conntrack_htable_size;
diff -urN --exclude-from=diff.exclude linux-2.4.20-base/net/ipv4/netfilter/ip_conntrack_core.c linux-2.4.20-del/net/ipv4/netfilter/ip_conntrack_core.c
--- linux-2.4.20-base/net/ipv4/netfilter/ip_conntrack_core.c Tue Feb 18 17:08:21 2003
+++ linux-2.4.20-del/net/ipv4/netfilter/ip_conntrack_core.c Fri Feb 21 17:01:39 2003
@@ -292,9 +292,6 @@
{
DEBUGP("clean_from_lists(%p)\n", ct);
MUST_BE_WRITE_LOCKED(&ip_conntrack_lock);
- /* Remove from both hash lists: must not NULL out next ptrs,
- otherwise we'll look unconfirmed. Fortunately, LIST_DELETE
- doesn't do this. --RR */
LIST_DELETE(&ip_conntrack_hash
[hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple)],
&ct->tuplehash[IP_CT_DIR_ORIGINAL]);
@@ -467,6 +464,7 @@
ct->timeout.expires += jiffies;
add_timer(&ct->timeout);
atomic_inc(&ct->ct_general.use);
+ set_bit(IPS_CONFIRMED_BIT, &ct->status);
WRITE_UNLOCK(&ip_conntrack_lock);
return NF_ACCEPT;
}
@@ -585,7 +583,7 @@
connection. Too bad: we're in trouble anyway. */
static inline int unreplied(const struct ip_conntrack_tuple_hash *i)
{
- return !(i->ctrack->status & IPS_ASSURED);
+ return !(test_bit(IPS_ASSURED_BIT, &i->ctrack->status));
}

static int early_drop(struct list_head *chain)
@@ -720,7 +718,7 @@
conntrack, expected);
/* Welcome, Mr. Bond. We've been expecting you... */
IP_NF_ASSERT(master_ct(conntrack));
- conntrack->status = IPS_EXPECTED;
+ __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
conntrack->master = expected;
expected->sibling = conntrack;
LIST_DELETE(&ip_conntrack_expect_list, expected);
@@ -768,11 +766,11 @@
*set_reply = 1;
} else {
/* Once we've had two way comms, always ESTABLISHED. */
- if (h->ctrack->status & IPS_SEEN_REPLY) {
+ if (test_bit(IPS_SEEN_REPLY_BIT, &h->ctrack->status)) {
DEBUGP("ip_conntrack_in: normal packet for %p\n",
h->ctrack);
*ctinfo = IP_CT_ESTABLISHED;
- } else if (h->ctrack->status & IPS_EXPECTED) {
+ } else if (test_bit(IPS_EXPECTED_BIT, &h->ctrack->status)) {
DEBUGP("ip_conntrack_in: related packet for %p\n",
h->ctrack);
*ctinfo = IP_CT_RELATED;
diff -urN --exclude-from=diff.exclude linux-2.4.20-base/net/ipv4/netfilter/ip_conntrack_proto_tcp.c linux-2.4.20-del/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
--- linux-2.4.20-base/net/ipv4/netfilter/ip_conntrack_proto_tcp.c Tue Feb 18 17:07:26 2003
+++ linux-2.4.20-del/net/ipv4/netfilter/ip_conntrack_proto_tcp.c Fri Feb 21 17:03:35 2003
@@ -192,7 +192,7 @@
have an established connection: this is a fairly common
problem case, so we can delete the conntrack
immediately. --RR */
- if (!(conntrack->status & IPS_SEEN_REPLY) && tcph->rst) {
+ if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) && tcph->rst) {
WRITE_UNLOCK(&tcp_lock);
if (del_timer(&conntrack->timeout))
conntrack->timeout.function((unsigned long)conntrack);
diff -urN --exclude-from=diff.exclude linux-2.4.20-base/net/ipv4/netfilter/ip_conntrack_proto_udp.c linux-2.4.20-del/net/ipv4/netfilter/ip_conntrack_proto_udp.c
--- linux-2.4.20-base/net/ipv4/netfilter/ip_conntrack_proto_udp.c Fri Nov 29 00:53:15 2002
+++ linux-2.4.20-del/net/ipv4/netfilter/ip_conntrack_proto_udp.c Fri Feb 21 17:01:39 2003
@@ -51,7 +51,7 @@
{
/* If we've seen traffic both ways, this is some kind of UDP
stream. Extend timeout. */
- if (conntrack->status & IPS_SEEN_REPLY) {
+ if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
ip_ct_refresh(conntrack, UDP_STREAM_TIMEOUT);
/* Also, more likely to be important, and not a probe */
set_bit(IPS_ASSURED_BIT, &conntrack->status);
diff -urN --exclude-from=diff.exclude linux-2.4.20-base/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.4.20-del/net/ipv4/netfilter/ip_conntrack_standalone.c
--- linux-2.4.20-base/net/ipv4/netfilter/ip_conntrack_standalone.c Fri Nov 29 00:53:15 2002
+++ linux-2.4.20-del/net/ipv4/netfilter/ip_conntrack_standalone.c Fri Feb 21 21:10:37 2003
@@ -77,7 +77,7 @@
}

static unsigned int
-print_conntrack(char *buffer, const struct ip_conntrack *conntrack)
+print_conntrack(char *buffer, struct ip_conntrack *conntrack)
{
unsigned int len;
struct ip_conntrack_protocol *proto
@@ -95,12 +95,12 @@
len += print_tuple(buffer + len,
&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
proto);
- if (!(conntrack->status & IPS_SEEN_REPLY))
+ if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
len += sprintf(buffer + len, "[UNREPLIED] ");
len += print_tuple(buffer + len,
&conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
proto);
- if (conntrack->status & IPS_ASSURED)
+ if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
len += sprintf(buffer + len, "[ASSURED] ");
len += sprintf(buffer + len, "use=%u ",
atomic_read(&conntrack->ct_general.use));
\
 
 \ /
  Last update: 2005-03-22 13:34    [W:7.225 / U:0.008 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site