From: Tom Parkin <tparkin@katalix.com>
To: netdev <netdev@vger.kernel.org>
Subject: kmemleak complaints in ip6mr.c
Date: Tue, 29 Jan 2013 18:51:27 +0000 [thread overview]
Message-ID: <20130129185127.GA31811@raven> (raw)
[-- Attachment #1: Type: text/plain, Size: 5737 bytes --]
I've discovered what may be a memory leak in ip6mr when using network
namespaces. Here's the kmemleak backtrace:
unreferenced object 0xf0d4a180 (size 96):
comm "ip", pid 6735, jiffies 4294949643 (age 73.268s)
hex dump (first 32 bytes):
68 a1 d4 f0 00 02 20 00 01 00 00 00 00 00 00 00 h..... .........
00 00 00 00 00 00 00 00 00 00 00 00 ff 7f 00 00 ................
backtrace:
[<c159b50c>] kmemleak_alloc+0x2c/0x60
[<c1139c23>] __kmalloc+0x1c3/0x240
[<c14e2627>] fib_default_rule_add+0x27/0x70
[<c157f8df>] ip6mr_net_init+0x6f/0x140
[<c14c4129>] ops_init+0x39/0x110
[<c14c425f>] setup_net+0x5f/0xf0
[<c14c46e4>] copy_net_ns+0x74/0xf0
[<c105fc81>] create_new_namespaces+0xd1/0x160
[<c105fedf>] unshare_nsproxy_namespaces+0x5f/0xa0
[<c1038a94>] sys_unshare+0x114/0x280
[<c15b7ecd>] sysenter_do_call+0x12/0x28
[<ffffffff>] 0xffffffff
I've reproduced this on a recent net-next kernel (master as of this
Monday or so, git hash cef401de7be8c4e155c6746bfccf721a4fa5fab9),
using the script attached inline below. The script is a trimmed down
version of something I have been using to stress test some l2tp_core
changes, but the ip6mr issue appears to exist on master as well as my
branch. To get this to show up on my AMD64x2 I typically have to run
the script twice -- the first time around I get a bunch of modprobe
complaints from kmemleak, and the second time around I get ip6mr
complaints.
I'm not sure whether the trace above represents a false positive or
not -- any thoughts?
Thanks,
Tom
#!/bin/bash
BRIDGE=br0
BASE_IP=172.16.0.0
PREFIX=24
MAX_CHILDREN=300
log() { echo -e "[$(date)] $@"; }
err() { log "ERROR: $@" 1>&2; false; }
die() { err "$@"; exit 1; }
dbg() { test -n "$DEBUG" && log "$@" 1>&2; }
# $1 -- ip as a dotted quad
ip_to_decimal()
{
local o1=${1%%.*}
local o2=$(echo "$1" | cut -d. -f2)
local o3=$(echo "$1" | cut -d. -f3)
local o4=${1##*.}
echo "($o1*(2^24)) + ($o2*(2^16)) + ($o3*(2^8)) + ($o4)" | bc
}
# $1 -- ip as a decimal number
decimal_to_ip()
{
local h=$(printf "%08x" "$1")
echo $(printf "%i" 0x${h:0:2}).$(printf "%i" 0x${h:2:2}).$(printf "%i" 0x${h:4:2}).$(printf "%i" 0x${h:6:2})
}
# $1 -- base
# $2 -- netmask
# $3 -- subnet index
offset_min_ipaddr()
{
local nwoff=$(echo "$3 * (2^(32-$2))" | bc)
local base=$(ip_to_decimal "$1")
decimal_to_ip $((base+nwoff+1))
}
#$1 -- lower bound
#$2 -- upper bound
brand() {
local r=$((RANDOM%$2))
test $r -lt $1 && r=$(brand $1 $2)
echo $r
}
# $1 -- network interface name
# $2 -- id
gen_script() {
local laddr=$(offset_min_ipaddr $BASE_IP $PREFIX $2)
local sleepfor=$(brand 0 5)
dbg "$2 : $1 : sleepfor $sleepfor"
cat << __EOF__
#!/bin/bash
ip addr add $laddr/255.255.0.0 dev $1 || exit 1
ip link set $1 up || exit 1
sleep $sleepfor
ip link set $1 down
__EOF__
}
# $1 -- netns
# $2 -- ve0
# $3 -- ve1
nsup() {
local netns="$1"
local ve0="$2"
local ve1="$3"
local ret=1
ip netns add $netns || return $ret
ip link add name $ve0 type veth peer name $ve1 && \
ip link set $ve1 netns $netns && \
brctl addif $BRIDGE $ve0 && \
ip link set $ve0 up && ret=0 || \
ip netns delete $netns
return $ret
}
# $1 -- netns
# $2 -- ve0
# $3 -- ve1
nsdown() {
local netns="$1"
local ve0="$2"
local ve1="$3"
ip link set $ve0 down
brctl delif $BRIDGE $ve0
ip link del $ve0
ip netns delete $netns
}
# $1 -- id
# $2 -- netns
do_netns() {
local id="$1"
local netns="$2"
local runscript=/tmp/${netns}_run.sh
local ve0=$(echo $netns | cut -d- -f1)-0
local ve1=$(echo $netns | cut -d- -f1)-1
dbg "$id : $netns"
if nsup $netns $ve0 $ve1
then
gen_script $ve1 $id > $runscript && chmod +x $runscript && \
ip netns exec $netns $runscript || \
err "$id : $netns failed to gen/exec ns script"
while ! nsdown $netns $ve0 $ve1 &> /dev/null; do sleep 1; done
rm $runscript
else
err "$id : $netns failed to come up"
fi
}
waitforchildren() {
local p=""
log "Wait for $(echo "$cpids" | wc -w) child scripts to complete"
dbg "cpids = $cpids"
for p in $cpids; do wait $p; done
cpids=""
}
#
# Entry point
#
trap waitforchildren EXIT
if ! brctl show | grep -q $BRIDGE
then
brctl addbr $BRIDGE || die "Failed to create bridge $BRIDGE"
ip link set $BRIDGE up || die "Failed to bring $BRIDGE up"
fi
c=0
cpids=""
while true
do
nchildren=$(brand 1 $MAX_CHILDREN)
echo clear > /sys/kernel/debug/kmemleak
log "Spawn $nchildren network namespaces"
for ((i=0;i<$nchildren;i++))
do
c=$((c+1))
netns=$(uuidgen)
( cpids=""; do_netns $c $netns ) &
cpids="$cpids $!"
done
waitforchildren
echo scan > /sys/kernel/debug/kmemleak
if test $(wc -l /sys/kernel/debug/kmemleak | cut -d" " -f1) -gt 0
then
die "Kernel memory leak detected: see /sys/kernel/debug/kmemleak"
fi
done
--
Tom Parkin
Katalix Systems Ltd
http://www.katalix.com
Catalysts for your Embedded Linux software development
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
next reply other threads:[~2013-01-29 18:51 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-29 18:51 Tom Parkin [this message]
2013-01-29 18:59 ` kmemleak complaints in ip6mr.c David Miller
2013-01-30 8:22 ` Cong Wang
2013-01-30 9:49 ` Tom Parkin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130129185127.GA31811@raven \
--to=tparkin@katalix.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.