* Re: 2.6.24 regression: reference count leak in PPPoE
From: Malte Schröder @ 2008-01-20 20:16 UTC (permalink / raw)
To: Andi Kleen; +Cc: netdev, linux-kernel
In-Reply-To: <200801202053.30386.ak@suse.de>
[-- Attachment #1: Type: text/plain, Size: 771 bytes --]
On Sun, 20 Jan 2008 20:53:30 +0100
Andi Kleen <ak@suse.de> wrote:
>
> My workstation running 2.6.24-rc8 just hung during shutdown with an endless
> (or rather I didn't wait more than a few minutes) loop of
>
> unregister_netdev: waiting for ppp-device to become free. Usage count = 1
>
> ppp-device was an active PPPoE device.
>
> No more information currently.
Now that you mention it, this happened to me too this morning. My
system stops the ppp interface (pppoe) and starts it again (my provider
shuts down the link every 24 hours, I want that to happen during the
night, so I do a ifdown ppp0).
--
---------------------------------------
Malte Schröder
MalteSch@gmx.de
ICQ# 68121508
---------------------------------------
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: 2.6.24 regression: reference count leak in PPPoE
From: Andi Kleen @ 2008-01-20 20:58 UTC (permalink / raw)
To: Ingo Molnar; +Cc: netdev, linux-kernel, Linus Torvalds
In-Reply-To: <20080120200109.GA31876@elte.hu>
> It seems to have stopped when i stopped using ipsec and started using
> vpnc.
Kernel ipsec was active yes. However I normally don't see it although
it is often active, that was the first time I think
(except long ago)
> (but no firm info - this was sporadic - happened every few months
> or so) Are you using ipsec and dynamic IPs by any chance?
and the ISP uses dynamic IPs.
-Andi
^ permalink raw reply
* [PATCH 4/4] dsmark: checkpatch warning cleanup
From: Stephen Hemminger @ 2008-01-20 21:25 UTC (permalink / raw)
To: David Miller; +Cc: Patrick McHardy, netdev
In-Reply-To: <20080120131008.2039a35d@deepthought>
Get rid of all style things checkpatch warns about, indentation
and whitespace.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/net/sched/sch_dsmark.c 2008-01-20 13:23:34.000000000 -0800
+++ b/net/sched/sch_dsmark.c 2008-01-20 13:24:45.000000000 -0800
@@ -152,7 +152,7 @@ static int dsmark_delete(struct Qdisc *s
return 0;
}
-static void dsmark_walk(struct Qdisc *sch,struct qdisc_walker *walker)
+static void dsmark_walk(struct Qdisc *sch, struct qdisc_walker *walker)
{
struct dsmark_qdisc_data *p = qdisc_priv(sch);
int i;
@@ -176,7 +176,8 @@ ignore:
}
}
-static inline struct tcf_proto **dsmark_find_tcf(struct Qdisc *sch,unsigned long cl)
+static inline struct tcf_proto **dsmark_find_tcf(struct Qdisc *sch,
+ unsigned long cl)
{
struct dsmark_qdisc_data *p = qdisc_priv(sch);
return &p->filter_list;
@@ -184,7 +185,7 @@ static inline struct tcf_proto **dsmark_
/* --------------------------- Qdisc operations ---------------------------- */
-static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
+static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
{
struct dsmark_qdisc_data *p = qdisc_priv(sch);
int err;
@@ -193,24 +194,24 @@ static int dsmark_enqueue(struct sk_buff
if (p->set_tc_index) {
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
- if (skb_cow_head(skb, sizeof(struct iphdr)))
- goto drop;
+ case __constant_htons(ETH_P_IP):
+ if (skb_cow_head(skb, sizeof(struct iphdr)))
+ goto drop;
- skb->tc_index = ipv4_get_dsfield(ip_hdr(skb))
- & ~INET_ECN_MASK;
- break;
+ skb->tc_index = ipv4_get_dsfield(ip_hdr(skb))
+ & ~INET_ECN_MASK;
+ break;
- case __constant_htons(ETH_P_IPV6):
- if (skb_cow_head(skb, sizeof(struct ipv6hdr)))
- goto drop;
+ case __constant_htons(ETH_P_IPV6):
+ if (skb_cow_head(skb, sizeof(struct ipv6hdr)))
+ goto drop;
- skb->tc_index = ipv6_get_dsfield(ipv6_hdr(skb))
- & ~INET_ECN_MASK;
- break;
- default:
- skb->tc_index = 0;
- break;
+ skb->tc_index = ipv6_get_dsfield(ipv6_hdr(skb))
+ & ~INET_ECN_MASK;
+ break;
+ default:
+ skb->tc_index = 0;
+ break;
}
}
@@ -243,7 +244,7 @@ static int dsmark_enqueue(struct sk_buff
}
}
- err = p->q->enqueue(skb,p->q);
+ err = p->q->enqueue(skb, p->q);
if (err != NET_XMIT_SUCCESS) {
sch->qstats.drops++;
return err;
@@ -279,31 +280,31 @@ static struct sk_buff *dsmark_dequeue(st
pr_debug("index %d->%d\n", skb->tc_index, index);
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
- ipv4_change_dsfield(ip_hdr(skb), p->mask[index],
- p->value[index]);
+ case __constant_htons(ETH_P_IP):
+ ipv4_change_dsfield(ip_hdr(skb), p->mask[index],
+ p->value[index]);
break;
- case __constant_htons(ETH_P_IPV6):
- ipv6_change_dsfield(ipv6_hdr(skb), p->mask[index],
- p->value[index]);
- break;
- default:
- /*
- * Only complain if a change was actually attempted.
- * This way, we can send non-IP traffic through dsmark
- * and don't need yet another qdisc as a bypass.
- */
- if (p->mask[index] != 0xff || p->value[index])
- printk(KERN_WARNING "dsmark_dequeue: "
- "unsupported protocol %d\n",
- ntohs(skb->protocol));
+ case __constant_htons(ETH_P_IPV6):
+ ipv6_change_dsfield(ipv6_hdr(skb), p->mask[index],
+ p->value[index]);
break;
+ default:
+ /*
+ * Only complain if a change was actually attempted.
+ * This way, we can send non-IP traffic through dsmark
+ * and don't need yet another qdisc as a bypass.
+ */
+ if (p->mask[index] != 0xff || p->value[index])
+ printk(KERN_WARNING
+ "dsmark_dequeue: unsupported protocol %d\n",
+ ntohs(skb->protocol));
+ break;
}
return skb;
}
-static int dsmark_requeue(struct sk_buff *skb,struct Qdisc *sch)
+static int dsmark_requeue(struct sk_buff *skb, struct Qdisc *sch)
{
struct dsmark_qdisc_data *p = qdisc_priv(sch);
int err;
@@ -423,8 +424,8 @@ static int dsmark_dump_class(struct Qdis
tcm->tcm_info = p->q->handle;
opts = RTA_NEST(skb, TCA_OPTIONS);
- RTA_PUT_U8(skb,TCA_DSMARK_MASK, p->mask[cl-1]);
- RTA_PUT_U8(skb,TCA_DSMARK_VALUE, p->value[cl-1]);
+ RTA_PUT_U8(skb, TCA_DSMARK_MASK, p->mask[cl-1]);
+ RTA_PUT_U8(skb, TCA_DSMARK_VALUE, p->value[cl-1]);
return RTA_NEST_END(skb, opts);
^ permalink raw reply
* [PATCH 2/4] dsmark: get rid of trivial function
From: Stephen Hemminger @ 2008-01-20 21:25 UTC (permalink / raw)
To: David Miller; +Cc: Patrick McHardy, netdev
In-Reply-To: <20080120130542.16720b45@deepthought>
Replace loop in dsmark_valid_indices with equivalent bit math.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/net/sched/sch_dsmark.c 2008-01-20 13:07:58.000000000 -0800
+++ b/net/sched/sch_dsmark.c 2008-01-20 13:22:54.000000000 -0800
@@ -45,13 +45,8 @@ struct dsmark_qdisc_data {
static inline int dsmark_valid_indices(u16 indices)
{
- while (indices != 1) {
- if (indices & 1)
- return 0;
- indices >>= 1;
- }
-
- return 1;
+ /* Must have only one bit set */
+ return (indices & (indices - 1)) == 0;
}
static inline int dsmark_valid_index(struct dsmark_qdisc_data *p, u16 index)
^ permalink raw reply
* [PATCH 1/4] dsmark: get rid of wrappers
From: Stephen Hemminger @ 2008-01-20 21:10 UTC (permalink / raw)
To: David Miller, Patrick McHardy; +Cc: netdev
Remove extraneous macro wrappers for printk and qdisc_priv.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/net/sched/sch_dsmark.c 2008-01-20 08:36:10.000000000 -0800
+++ b/net/sched/sch_dsmark.c 2008-01-20 08:47:26.000000000 -0800
@@ -15,23 +15,6 @@
#include <net/inet_ecn.h>
#include <asm/byteorder.h>
-
-#if 0 /* control */
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
-#if 0 /* data */
-#define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define D2PRINTK(format,args...)
-#endif
-
-
-#define PRIV(sch) ((struct dsmark_qdisc_data *) qdisc_priv(sch))
-
-
/*
* classid class marking
* ------- ----- -------
@@ -81,9 +64,9 @@ static inline int dsmark_valid_index(str
static int dsmark_graft(struct Qdisc *sch, unsigned long arg,
struct Qdisc *new, struct Qdisc **old)
{
- struct dsmark_qdisc_data *p = PRIV(sch);
+ struct dsmark_qdisc_data *p = qdisc_priv(sch);
- DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",
+ pr_debug("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",
sch, p, new, old);
if (new == NULL) {
@@ -104,13 +87,14 @@ static int dsmark_graft(struct Qdisc *sc
static struct Qdisc *dsmark_leaf(struct Qdisc *sch, unsigned long arg)
{
- return PRIV(sch)->q;
+ struct dsmark_qdisc_data *p = qdisc_priv(sch);
+ return p->q;
}
static unsigned long dsmark_get(struct Qdisc *sch, u32 classid)
{
- DPRINTK("dsmark_get(sch %p,[qdisc %p],classid %x)\n",
- sch, PRIV(sch), classid);
+ pr_debug("dsmark_get(sch %p,[qdisc %p],classid %x)\n",
+ sch, qdisc_priv(sch), classid);
return TC_H_MIN(classid) + 1;
}
@@ -128,13 +112,13 @@ static void dsmark_put(struct Qdisc *sch
static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent,
struct rtattr **tca, unsigned long *arg)
{
- struct dsmark_qdisc_data *p = PRIV(sch);
+ struct dsmark_qdisc_data *p = qdisc_priv(sch);
struct rtattr *opt = tca[TCA_OPTIONS-1];
struct rtattr *tb[TCA_DSMARK_MAX];
int err = -EINVAL;
u8 mask = 0;
- DPRINTK("dsmark_change(sch %p,[qdisc %p],classid %x,parent %x),"
+ pr_debug("dsmark_change(sch %p,[qdisc %p],classid %x,parent %x),"
"arg 0x%lx\n", sch, p, classid, parent, *arg);
if (!dsmark_valid_index(p, *arg)) {
@@ -162,7 +146,7 @@ rtattr_failure:
static int dsmark_delete(struct Qdisc *sch, unsigned long arg)
{
- struct dsmark_qdisc_data *p = PRIV(sch);
+ struct dsmark_qdisc_data *p = qdisc_priv(sch);
if (!dsmark_valid_index(p, arg))
return -EINVAL;
@@ -175,10 +159,10 @@ static int dsmark_delete(struct Qdisc *s
static void dsmark_walk(struct Qdisc *sch,struct qdisc_walker *walker)
{
- struct dsmark_qdisc_data *p = PRIV(sch);
+ struct dsmark_qdisc_data *p = qdisc_priv(sch);
int i;
- DPRINTK("dsmark_walk(sch %p,[qdisc %p],walker %p)\n", sch, p, walker);
+ pr_debug("dsmark_walk(sch %p,[qdisc %p],walker %p)\n", sch, p, walker);
if (walker->stop)
return;
@@ -197,19 +181,20 @@ ignore:
}
}
-static struct tcf_proto **dsmark_find_tcf(struct Qdisc *sch,unsigned long cl)
+static inline struct tcf_proto **dsmark_find_tcf(struct Qdisc *sch,unsigned long cl)
{
- return &PRIV(sch)->filter_list;
+ struct dsmark_qdisc_data *p = qdisc_priv(sch);
+ return &p->filter_list;
}
/* --------------------------- Qdisc operations ---------------------------- */
static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
{
- struct dsmark_qdisc_data *p = PRIV(sch);
+ struct dsmark_qdisc_data *p = qdisc_priv(sch);
int err;
- D2PRINTK("dsmark_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
+ pr_debug("dsmark_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
if (p->set_tc_index) {
/* FIXME: Safe with non-linear skbs? --RR */
@@ -234,7 +219,7 @@ static int dsmark_enqueue(struct sk_buff
struct tcf_result res;
int result = tc_classify(skb, p->filter_list, &res);
- D2PRINTK("result %d class 0x%04x\n", result, res.classid);
+ pr_debug("result %d class 0x%04x\n", result, res.classid);
switch (result) {
#ifdef CONFIG_NET_CLS_ACT
@@ -272,11 +257,11 @@ static int dsmark_enqueue(struct sk_buff
static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
{
- struct dsmark_qdisc_data *p = PRIV(sch);
+ struct dsmark_qdisc_data *p = qdisc_priv(sch);
struct sk_buff *skb;
u32 index;
- D2PRINTK("dsmark_dequeue(sch %p,[qdisc %p])\n", sch, p);
+ pr_debug("dsmark_dequeue(sch %p,[qdisc %p])\n", sch, p);
skb = p->q->ops->dequeue(p->q);
if (skb == NULL)
@@ -285,7 +270,7 @@ static struct sk_buff *dsmark_dequeue(st
sch->q.qlen--;
index = skb->tc_index & (p->indices - 1);
- D2PRINTK("index %d->%d\n", skb->tc_index, index);
+ pr_debug("index %d->%d\n", skb->tc_index, index);
switch (skb->protocol) {
case __constant_htons(ETH_P_IP):
@@ -314,10 +299,10 @@ static struct sk_buff *dsmark_dequeue(st
static int dsmark_requeue(struct sk_buff *skb,struct Qdisc *sch)
{
- struct dsmark_qdisc_data *p = PRIV(sch);
+ struct dsmark_qdisc_data *p = qdisc_priv(sch);
int err;
- D2PRINTK("dsmark_requeue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
+ pr_debug("dsmark_requeue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
err = p->q->ops->requeue(skb, p->q);
if (err != NET_XMIT_SUCCESS) {
@@ -333,10 +318,10 @@ static int dsmark_requeue(struct sk_buff
static unsigned int dsmark_drop(struct Qdisc *sch)
{
- struct dsmark_qdisc_data *p = PRIV(sch);
+ struct dsmark_qdisc_data *p = qdisc_priv(sch);
unsigned int len;
- DPRINTK("dsmark_reset(sch %p,[qdisc %p])\n", sch, p);
+ pr_debug("dsmark_reset(sch %p,[qdisc %p])\n", sch, p);
if (p->q->ops->drop == NULL)
return 0;
@@ -350,14 +335,14 @@ static unsigned int dsmark_drop(struct Q
static int dsmark_init(struct Qdisc *sch, struct rtattr *opt)
{
- struct dsmark_qdisc_data *p = PRIV(sch);
+ struct dsmark_qdisc_data *p = qdisc_priv(sch);
struct rtattr *tb[TCA_DSMARK_MAX];
int err = -EINVAL;
u32 default_index = NO_DEFAULT_INDEX;
u16 indices;
u8 *mask;
- DPRINTK("dsmark_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt);
+ pr_debug("dsmark_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt);
if (!opt || rtattr_parse_nested(tb, TCA_DSMARK_MAX, opt) < 0)
goto errout;
@@ -389,7 +374,7 @@ static int dsmark_init(struct Qdisc *sch
if (p->q == NULL)
p->q = &noop_qdisc;
- DPRINTK("dsmark_init: qdisc %p\n", p->q);
+ pr_debug("dsmark_init: qdisc %p\n", p->q);
err = 0;
errout:
@@ -399,18 +384,18 @@ rtattr_failure:
static void dsmark_reset(struct Qdisc *sch)
{
- struct dsmark_qdisc_data *p = PRIV(sch);
+ struct dsmark_qdisc_data *p = qdisc_priv(sch);
- DPRINTK("dsmark_reset(sch %p,[qdisc %p])\n", sch, p);
+ pr_debug("dsmark_reset(sch %p,[qdisc %p])\n", sch, p);
qdisc_reset(p->q);
sch->q.qlen = 0;
}
static void dsmark_destroy(struct Qdisc *sch)
{
- struct dsmark_qdisc_data *p = PRIV(sch);
+ struct dsmark_qdisc_data *p = qdisc_priv(sch);
- DPRINTK("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p);
+ pr_debug("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p);
tcf_destroy_chain(p->filter_list);
qdisc_destroy(p->q);
@@ -420,10 +405,10 @@ static void dsmark_destroy(struct Qdisc
static int dsmark_dump_class(struct Qdisc *sch, unsigned long cl,
struct sk_buff *skb, struct tcmsg *tcm)
{
- struct dsmark_qdisc_data *p = PRIV(sch);
+ struct dsmark_qdisc_data *p = qdisc_priv(sch);
struct rtattr *opts = NULL;
- DPRINTK("dsmark_dump_class(sch %p,[qdisc %p],class %ld\n", sch, p, cl);
+ pr_debug("dsmark_dump_class(sch %p,[qdisc %p],class %ld\n", sch, p, cl);
if (!dsmark_valid_index(p, cl))
return -EINVAL;
@@ -443,7 +428,7 @@ rtattr_failure:
static int dsmark_dump(struct Qdisc *sch, struct sk_buff *skb)
{
- struct dsmark_qdisc_data *p = PRIV(sch);
+ struct dsmark_qdisc_data *p = qdisc_priv(sch);
struct rtattr *opts = NULL;
opts = RTA_NEST(skb, TCA_OPTIONS);
^ permalink raw reply
* [PATCH 3/4] dsmark: handle cloned and non-linear skb's
From: Stephen Hemminger @ 2008-01-20 21:23 UTC (permalink / raw)
To: David Miller; +Cc: Patrick McHardy, netdev
In-Reply-To: <20080120131008.2039a35d@deepthought>
Make dsmark work properly with non-linear and cloned skb's
Before modifying the header, it needs to check that skb header is
writeable.
Note: this makes the assumption, that if it queues a good skb
then a good skb will come out of the embedded qdisc.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/net/sched/sch_dsmark.c 2008-01-20 13:22:54.000000000 -0800
+++ b/net/sched/sch_dsmark.c 2008-01-20 13:23:34.000000000 -0800
@@ -192,13 +192,19 @@ static int dsmark_enqueue(struct sk_buff
pr_debug("dsmark_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
if (p->set_tc_index) {
- /* FIXME: Safe with non-linear skbs? --RR */
switch (skb->protocol) {
case __constant_htons(ETH_P_IP):
+ if (skb_cow_head(skb, sizeof(struct iphdr)))
+ goto drop;
+
skb->tc_index = ipv4_get_dsfield(ip_hdr(skb))
& ~INET_ECN_MASK;
break;
+
case __constant_htons(ETH_P_IPV6):
+ if (skb_cow_head(skb, sizeof(struct ipv6hdr)))
+ goto drop;
+
skb->tc_index = ipv6_get_dsfield(ipv6_hdr(skb))
& ~INET_ECN_MASK;
break;
@@ -222,14 +228,14 @@ static int dsmark_enqueue(struct sk_buff
case TC_ACT_STOLEN:
kfree_skb(skb);
return NET_XMIT_SUCCESS;
+
case TC_ACT_SHOT:
- kfree_skb(skb);
- sch->qstats.drops++;
- return NET_XMIT_BYPASS;
+ goto drop;
#endif
case TC_ACT_OK:
skb->tc_index = TC_H_MIN(res.classid);
break;
+
default:
if (p->default_index != NO_DEFAULT_INDEX)
skb->tc_index = p->default_index;
@@ -248,6 +254,11 @@ static int dsmark_enqueue(struct sk_buff
sch->q.qlen++;
return NET_XMIT_SUCCESS;
+
+drop:
+ kfree_skb(skb);
+ sch->qstats.drops++;
+ return NET_XMIT_BYPASS;
}
static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
^ permalink raw reply
* [PATCH] sch_atm: style cleanup
From: Stephen Hemminger @ 2008-01-20 22:03 UTC (permalink / raw)
To: David Miller, Patrick McHardy, Chas Williams; +Cc: netdev, linux-atm-general
ATM scheduler clean house:
* get rid of printk and qdisc_priv() wrapper
* split some assignment in if() statements
* whitespace and line breaks.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/net/sched/sch_atm.c 2008-01-20 13:51:58.000000000 -0800
+++ b/net/sched/sch_atm.c 2008-01-20 13:59:16.000000000 -0800
@@ -16,18 +16,6 @@
extern struct socket *sockfd_lookup(int fd, int *err); /* @@@ fix this */
-#if 0 /* control */
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
-#if 0 /* data */
-#define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define D2PRINTK(format,args...)
-#endif
-
/*
* The ATM queuing discipline provides a framework for invoking classifiers
* (aka "filters"), which in turn select classes of this queuing discipline.
@@ -49,7 +37,6 @@ extern struct socket *sockfd_lookup(int
* - should lock the flow while there is data in the queue (?)
*/
-#define PRIV(sch) qdisc_priv(sch)
#define VCC2FLOW(vcc) ((struct atm_flow_data *) ((vcc)->user_back))
struct atm_flow_data {
@@ -57,7 +44,7 @@ struct atm_flow_data {
struct tcf_proto *filter_list;
struct atm_vcc *vcc; /* VCC; NULL if VCC is closed */
void (*old_pop)(struct atm_vcc *vcc,
- struct sk_buff * skb); /* chaining */
+ struct sk_buff *skb); /* chaining */
struct atm_qdisc_data *parent; /* parent qdisc */
struct socket *sock; /* for closing */
u32 classid; /* x:y type ID */
@@ -84,17 +71,17 @@ static int find_flow(struct atm_qdisc_da
{
struct atm_flow_data *walk;
- DPRINTK("find_flow(qdisc %p,flow %p)\n", qdisc, flow);
+ pr_debug("find_flow(qdisc %p,flow %p)\n", qdisc, flow);
for (walk = qdisc->flows; walk; walk = walk->next)
if (walk == flow)
return 1;
- DPRINTK("find_flow: not found\n");
+ pr_debug("find_flow: not found\n");
return 0;
}
static inline struct atm_flow_data *lookup_flow(struct Qdisc *sch, u32 classid)
{
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
struct atm_flow_data *flow;
for (flow = p->flows; flow; flow = flow->next)
@@ -106,10 +93,10 @@ static inline struct atm_flow_data *look
static int atm_tc_graft(struct Qdisc *sch, unsigned long arg,
struct Qdisc *new, struct Qdisc **old)
{
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
struct atm_flow_data *flow = (struct atm_flow_data *)arg;
- DPRINTK("atm_tc_graft(sch %p,[qdisc %p],flow %p,new %p,old %p)\n",
+ pr_debug("atm_tc_graft(sch %p,[qdisc %p],flow %p,new %p,old %p)\n",
sch, p, flow, new, old);
if (!find_flow(p, flow))
return -EINVAL;
@@ -125,20 +112,20 @@ static struct Qdisc *atm_tc_leaf(struct
{
struct atm_flow_data *flow = (struct atm_flow_data *)cl;
- DPRINTK("atm_tc_leaf(sch %p,flow %p)\n", sch, flow);
+ pr_debug("atm_tc_leaf(sch %p,flow %p)\n", sch, flow);
return flow ? flow->q : NULL;
}
static unsigned long atm_tc_get(struct Qdisc *sch, u32 classid)
{
- struct atm_qdisc_data *p __maybe_unused = PRIV(sch);
+ struct atm_qdisc_data *p __maybe_unused = qdisc_priv(sch);
struct atm_flow_data *flow;
- DPRINTK("atm_tc_get(sch %p,[qdisc %p],classid %x)\n", sch, p, classid);
+ pr_debug("atm_tc_get(sch %p,[qdisc %p],classid %x)\n", sch, p, classid);
flow = lookup_flow(sch, classid);
if (flow)
flow->ref++;
- DPRINTK("atm_tc_get: flow %p\n", flow);
+ pr_debug("atm_tc_get: flow %p\n", flow);
return (unsigned long)flow;
}
@@ -155,14 +142,14 @@ static unsigned long atm_tc_bind_filter(
*/
static void atm_tc_put(struct Qdisc *sch, unsigned long cl)
{
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
struct atm_flow_data *flow = (struct atm_flow_data *)cl;
struct atm_flow_data **prev;
- DPRINTK("atm_tc_put(sch %p,[qdisc %p],flow %p)\n", sch, p, flow);
+ pr_debug("atm_tc_put(sch %p,[qdisc %p],flow %p)\n", sch, p, flow);
if (--flow->ref)
return;
- DPRINTK("atm_tc_put: destroying\n");
+ pr_debug("atm_tc_put: destroying\n");
for (prev = &p->flows; *prev; prev = &(*prev)->next)
if (*prev == flow)
break;
@@ -171,11 +158,11 @@ static void atm_tc_put(struct Qdisc *sch
return;
}
*prev = flow->next;
- DPRINTK("atm_tc_put: qdisc %p\n", flow->q);
+ pr_debug("atm_tc_put: qdisc %p\n", flow->q);
qdisc_destroy(flow->q);
tcf_destroy_chain(flow->filter_list);
if (flow->sock) {
- DPRINTK("atm_tc_put: f_count %d\n",
+ pr_debug("atm_tc_put: f_count %d\n",
file_count(flow->sock->file));
flow->vcc->pop = flow->old_pop;
sockfd_put(flow->sock);
@@ -194,7 +181,7 @@ static void sch_atm_pop(struct atm_vcc *
{
struct atm_qdisc_data *p = VCC2FLOW(vcc)->parent;
- D2PRINTK("sch_atm_pop(vcc %p,skb %p,[qdisc %p])\n", vcc, skb, p);
+ pr_debug("sch_atm_pop(vcc %p,skb %p,[qdisc %p])\n", vcc, skb, p);
VCC2FLOW(vcc)->old_pop(vcc, skb);
tasklet_schedule(&p->task);
}
@@ -211,7 +198,7 @@ static const u8 llc_oui_ip[] = {
static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
struct rtattr **tca, unsigned long *arg)
{
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
struct atm_flow_data *flow = (struct atm_flow_data *)*arg;
struct atm_flow_data *excess = NULL;
struct rtattr *opt = tca[TCA_OPTIONS - 1];
@@ -220,7 +207,7 @@ static int atm_tc_change(struct Qdisc *s
int fd, error, hdr_len;
void *hdr;
- DPRINTK("atm_tc_change(sch %p,[qdisc %p],classid %x,parent %x,"
+ pr_debug("atm_tc_change(sch %p,[qdisc %p],classid %x,parent %x,"
"flow %p,opt %p)\n", sch, p, classid, parent, flow, opt);
/*
* The concept of parents doesn't apply for this qdisc.
@@ -241,7 +228,7 @@ static int atm_tc_change(struct Qdisc *s
if (!tb[TCA_ATM_FD - 1] || RTA_PAYLOAD(tb[TCA_ATM_FD - 1]) < sizeof(fd))
return -EINVAL;
fd = *(int *)RTA_DATA(tb[TCA_ATM_FD - 1]);
- DPRINTK("atm_tc_change: fd %d\n", fd);
+ pr_debug("atm_tc_change: fd %d\n", fd);
if (tb[TCA_ATM_HDR - 1]) {
hdr_len = RTA_PAYLOAD(tb[TCA_ATM_HDR - 1]);
hdr = RTA_DATA(tb[TCA_ATM_HDR - 1]);
@@ -259,11 +246,12 @@ static int atm_tc_change(struct Qdisc *s
if (!excess)
return -ENOENT;
}
- DPRINTK("atm_tc_change: type %d, payload %d, hdr_len %d\n",
- opt->rta_type, RTA_PAYLOAD(opt), hdr_len);
- if (!(sock = sockfd_lookup(fd, &error)))
+ pr_debug("atm_tc_change: type %d, payload %lu, hdr_len %d\n",
+ opt->rta_type, RTA_PAYLOAD(opt), hdr_len);
+ sock = sockfd_lookup(fd, &error);
+ if (!sock)
return error; /* f_count++ */
- DPRINTK("atm_tc_change: f_count %d\n", file_count(sock->file));
+ pr_debug("atm_tc_change: f_count %d\n", file_count(sock->file));
if (sock->ops->family != PF_ATMSVC && sock->ops->family != PF_ATMPVC) {
error = -EPROTOTYPE;
goto err_out;
@@ -272,7 +260,7 @@ static int atm_tc_change(struct Qdisc *s
on vcc->send */
if (classid) {
if (TC_H_MAJ(classid ^ sch->handle)) {
- DPRINTK("atm_tc_change: classid mismatch\n");
+ pr_debug("atm_tc_change: classid mismatch\n");
error = -EINVAL;
goto err_out;
}
@@ -286,26 +274,28 @@ static int atm_tc_change(struct Qdisc *s
for (i = 1; i < 0x8000; i++) {
classid = TC_H_MAKE(sch->handle, 0x8000 | i);
- if (!(cl = atm_tc_get(sch, classid)))
+ cl = atm_tc_get(sch, classid);
+ if (!cl)
break;
atm_tc_put(sch, cl);
}
}
- DPRINTK("atm_tc_change: new id %x\n", classid);
+ pr_debug("atm_tc_change: new id %x\n", classid);
flow = kzalloc(sizeof(struct atm_flow_data) + hdr_len, GFP_KERNEL);
- DPRINTK("atm_tc_change: flow %p\n", flow);
+ pr_debug("atm_tc_change: flow %p\n", flow);
if (!flow) {
error = -ENOBUFS;
goto err_out;
}
flow->filter_list = NULL;
- if (!(flow->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid)))
+ flow->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid);
+ if (!flow->q)
flow->q = &noop_qdisc;
- DPRINTK("atm_tc_change: qdisc %p\n", flow->q);
+ pr_debug("atm_tc_change: qdisc %p\n", flow->q);
flow->sock = sock;
flow->vcc = ATM_SD(sock); /* speedup */
flow->vcc->user_back = flow;
- DPRINTK("atm_tc_change: vcc %p\n", flow->vcc);
+ pr_debug("atm_tc_change: vcc %p\n", flow->vcc);
flow->old_pop = flow->vcc->pop;
flow->parent = p;
flow->vcc->pop = sch_atm_pop;
@@ -330,11 +320,11 @@ err_out:
static int atm_tc_delete(struct Qdisc *sch, unsigned long arg)
{
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
struct atm_flow_data *flow = (struct atm_flow_data *)arg;
- DPRINTK("atm_tc_delete(sch %p,[qdisc %p],flow %p)\n", sch, p, flow);
- if (!find_flow(PRIV(sch), flow))
+ pr_debug("atm_tc_delete(sch %p,[qdisc %p],flow %p)\n", sch, p, flow);
+ if (!find_flow(qdisc_priv(sch), flow))
return -EINVAL;
if (flow->filter_list || flow == &p->link)
return -EBUSY;
@@ -354,10 +344,10 @@ static int atm_tc_delete(struct Qdisc *s
static void atm_tc_walk(struct Qdisc *sch, struct qdisc_walker *walker)
{
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
struct atm_flow_data *flow;
- DPRINTK("atm_tc_walk(sch %p,[qdisc %p],walker %p)\n", sch, p, walker);
+ pr_debug("atm_tc_walk(sch %p,[qdisc %p],walker %p)\n", sch, p, walker);
if (walker->stop)
return;
for (flow = p->flows; flow; flow = flow->next) {
@@ -372,10 +362,10 @@ static void atm_tc_walk(struct Qdisc *sc
static struct tcf_proto **atm_tc_find_tcf(struct Qdisc *sch, unsigned long cl)
{
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
struct atm_flow_data *flow = (struct atm_flow_data *)cl;
- DPRINTK("atm_tc_find_tcf(sch %p,[qdisc %p],flow %p)\n", sch, p, flow);
+ pr_debug("atm_tc_find_tcf(sch %p,[qdisc %p],flow %p)\n", sch, p, flow);
return flow ? &flow->filter_list : &p->link.filter_list;
}
@@ -383,13 +373,13 @@ static struct tcf_proto **atm_tc_find_tc
static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
{
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
struct atm_flow_data *flow = NULL; /* @@@ */
struct tcf_result res;
int result;
int ret = NET_XMIT_POLICED;
- D2PRINTK("atm_tc_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
+ pr_debug("atm_tc_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
result = TC_POLICE_OK; /* be nice to gcc */
if (TC_H_MAJ(skb->priority) != sch->handle ||
!(flow = (struct atm_flow_data *)atm_tc_get(sch, skb->priority)))
@@ -430,7 +420,8 @@ static int atm_tc_enqueue(struct sk_buff
#endif
}
- if ((ret = flow->q->enqueue(skb, flow->q)) != 0) {
+ ret = flow->q->enqueue(skb, flow->q);
+ if (ret != 0) {
drop: __maybe_unused
sch->qstats.drops++;
if (flow)
@@ -468,11 +459,11 @@ drop: __maybe_unused
static void sch_atm_dequeue(unsigned long data)
{
struct Qdisc *sch = (struct Qdisc *)data;
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
struct atm_flow_data *flow;
struct sk_buff *skb;
- D2PRINTK("sch_atm_dequeue(sch %p,[qdisc %p])\n", sch, p);
+ pr_debug("sch_atm_dequeue(sch %p,[qdisc %p])\n", sch, p);
for (flow = p->link.next; flow; flow = flow->next)
/*
* If traffic is properly shaped, this won't generate nasty
@@ -483,7 +474,7 @@ static void sch_atm_dequeue(unsigned lon
(void)flow->q->ops->requeue(skb, flow->q);
break;
}
- D2PRINTK("atm_tc_dequeue: sending on class %p\n", flow);
+ pr_debug("atm_tc_dequeue: sending on class %p\n", flow);
/* remove any LL header somebody else has attached */
skb_pull(skb, skb_network_offset(skb));
if (skb_headroom(skb) < flow->hdr_len) {
@@ -495,7 +486,7 @@ static void sch_atm_dequeue(unsigned lon
continue;
skb = new;
}
- D2PRINTK("sch_atm_dequeue: ip %p, data %p\n",
+ pr_debug("sch_atm_dequeue: ip %p, data %p\n",
skb_network_header(skb), skb->data);
ATM_SKB(skb)->vcc = flow->vcc;
memcpy(skb_push(skb, flow->hdr_len), flow->hdr,
@@ -509,10 +500,10 @@ static void sch_atm_dequeue(unsigned lon
static struct sk_buff *atm_tc_dequeue(struct Qdisc *sch)
{
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
struct sk_buff *skb;
- D2PRINTK("atm_tc_dequeue(sch %p,[qdisc %p])\n", sch, p);
+ pr_debug("atm_tc_dequeue(sch %p,[qdisc %p])\n", sch, p);
tasklet_schedule(&p->task);
skb = p->link.q->dequeue(p->link.q);
if (skb)
@@ -522,10 +513,10 @@ static struct sk_buff *atm_tc_dequeue(st
static int atm_tc_requeue(struct sk_buff *skb, struct Qdisc *sch)
{
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
int ret;
- D2PRINTK("atm_tc_requeue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
+ pr_debug("atm_tc_requeue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
ret = p->link.q->ops->requeue(skb, p->link.q);
if (!ret) {
sch->q.qlen++;
@@ -539,11 +530,11 @@ static int atm_tc_requeue(struct sk_buff
static unsigned int atm_tc_drop(struct Qdisc *sch)
{
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
struct atm_flow_data *flow;
unsigned int len;
- DPRINTK("atm_tc_drop(sch %p,[qdisc %p])\n", sch, p);
+ pr_debug("atm_tc_drop(sch %p,[qdisc %p])\n", sch, p);
for (flow = p->flows; flow; flow = flow->next)
if (flow->q->ops->drop && (len = flow->q->ops->drop(flow->q)))
return len;
@@ -552,14 +543,14 @@ static unsigned int atm_tc_drop(struct Q
static int atm_tc_init(struct Qdisc *sch, struct rtattr *opt)
{
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
- DPRINTK("atm_tc_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt);
+ pr_debug("atm_tc_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt);
p->flows = &p->link;
- if (!(p->link.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
- sch->handle)))
+ p->link.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, sch->handle);
+ if (!p->link.q)
p->link.q = &noop_qdisc;
- DPRINTK("atm_tc_init: link (%p) qdisc %p\n", &p->link, p->link.q);
+ pr_debug("atm_tc_init: link (%p) qdisc %p\n", &p->link, p->link.q);
p->link.filter_list = NULL;
p->link.vcc = NULL;
p->link.sock = NULL;
@@ -572,10 +563,10 @@ static int atm_tc_init(struct Qdisc *sch
static void atm_tc_reset(struct Qdisc *sch)
{
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
struct atm_flow_data *flow;
- DPRINTK("atm_tc_reset(sch %p,[qdisc %p])\n", sch, p);
+ pr_debug("atm_tc_reset(sch %p,[qdisc %p])\n", sch, p);
for (flow = p->flows; flow; flow = flow->next)
qdisc_reset(flow->q);
sch->q.qlen = 0;
@@ -583,10 +574,10 @@ static void atm_tc_reset(struct Qdisc *s
static void atm_tc_destroy(struct Qdisc *sch)
{
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
struct atm_flow_data *flow;
- DPRINTK("atm_tc_destroy(sch %p,[qdisc %p])\n", sch, p);
+ pr_debug("atm_tc_destroy(sch %p,[qdisc %p])\n", sch, p);
/* races ? */
while ((flow = p->flows)) {
tcf_destroy_chain(flow->filter_list);
@@ -608,12 +599,12 @@ static void atm_tc_destroy(struct Qdisc
static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
struct sk_buff *skb, struct tcmsg *tcm)
{
- struct atm_qdisc_data *p = PRIV(sch);
+ struct atm_qdisc_data *p = qdisc_priv(sch);
struct atm_flow_data *flow = (struct atm_flow_data *)cl;
unsigned char *b = skb_tail_pointer(skb);
struct rtattr *rta;
- DPRINTK("atm_tc_dump_class(sch %p,[qdisc %p],flow %p,skb %p,tcm %p)\n",
+ pr_debug("atm_tc_dump_class(sch %p,[qdisc %p],flow %p,skb %p,tcm %p)\n",
sch, p, flow, skb, tcm);
if (!find_flow(p, flow))
return -EINVAL;
^ permalink raw reply
* [PATCH] net classifier: style cleanup's
From: Stephen Hemminger @ 2008-01-20 22:06 UTC (permalink / raw)
To: David Miller, Patrick McHardy; +Cc: netdev
Classifier code cleanup. Get rid of printk wrapper, and fix whitespace
and other style stuff reported by checkpatch
---
net/sched/cls_api.c | 100 +++++++++++++++++++++++-------------------------
net/sched/cls_tcindex.c | 60 +++++++++++-----------------
2 files changed, 73 insertions(+), 87 deletions(-)
--- a/net/sched/cls_api.c 2008-01-20 13:33:11.000000000 -0800
+++ b/net/sched/cls_api.c 2008-01-20 13:46:04.000000000 -0800
@@ -29,12 +29,6 @@
#include <net/pkt_sched.h>
#include <net/pkt_cls.h>
-#if 0 /* control */
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
/* The list of all installed classifier types */
static struct tcf_proto_ops *tcf_proto_base;
@@ -44,7 +38,7 @@ static DEFINE_RWLOCK(cls_mod_lock);
/* Find classifier type by string name */
-static struct tcf_proto_ops * tcf_proto_lookup_ops(struct rtattr *kind)
+static struct tcf_proto_ops *tcf_proto_lookup_ops(struct rtattr *kind)
{
struct tcf_proto_ops *t = NULL;
@@ -81,6 +75,7 @@ out:
write_unlock(&cls_mod_lock);
return rc;
}
+EXPORT_SYMBOL(register_tcf_proto_ops);
int unregister_tcf_proto_ops(struct tcf_proto_ops *ops)
{
@@ -100,6 +95,7 @@ out:
write_unlock(&cls_mod_lock);
return rc;
}
+EXPORT_SYMBOL(unregister_tcf_proto_ops);
static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n,
struct tcf_proto *tp, unsigned long fh, int event);
@@ -107,9 +103,9 @@ static int tfilter_notify(struct sk_buff
/* Select new prio value from the range, managed by kernel. */
-static __inline__ u32 tcf_auto_prio(struct tcf_proto *tp)
+static inline u32 tcf_auto_prio(struct tcf_proto *tp)
{
- u32 first = TC_H_MAKE(0xC0000000U,0U);
+ u32 first = TC_H_MAKE(0xC0000000U, 0U);
if (tp)
first = tp->prio-1;
@@ -154,21 +150,25 @@ replay:
/* If no priority is given, user wants we allocated it. */
if (n->nlmsg_type != RTM_NEWTFILTER || !(n->nlmsg_flags&NLM_F_CREATE))
return -ENOENT;
- prio = TC_H_MAKE(0x80000000U,0U);
+ prio = TC_H_MAKE(0x80000000U, 0U);
}
/* Find head of filter chain. */
/* Find link */
- if ((dev = __dev_get_by_index(&init_net, t->tcm_ifindex)) == NULL)
+ dev = __dev_get_by_index(&init_net, t->tcm_ifindex);
+ if (dev == NULL)
return -ENODEV;
/* Find qdisc */
if (!parent) {
q = dev->qdisc_sleeping;
parent = q->handle;
- } else if ((q = qdisc_lookup(dev, TC_H_MAJ(t->tcm_parent))) == NULL)
- return -EINVAL;
+ } else {
+ q = qdisc_lookup(dev, TC_H_MAJ(t->tcm_parent));
+ if (q == NULL)
+ return -EINVAL;
+ }
/* Is it classful? */
if ((cops = q->ops->cl_ops) == NULL)
@@ -213,7 +213,8 @@ replay:
/* Create new proto tcf */
err = -ENOBUFS;
- if ((tp = kzalloc(sizeof(*tp), GFP_KERNEL)) == NULL)
+ tp = kzalloc(sizeof(*tp), GFP_KERNEL);
+ if (tp == NULL)
goto errout;
err = -EINVAL;
tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND-1]);
@@ -249,7 +250,9 @@ replay:
tp->q = q;
tp->classify = tp_ops->classify;
tp->classid = parent;
- if ((err = tp_ops->init(tp)) != 0) {
+
+ err = tp_ops->init(tp);
+ if (err != 0) {
module_put(tp_ops->owner);
kfree(tp);
goto errout;
@@ -278,13 +281,14 @@ replay:
}
err = -ENOENT;
- if (n->nlmsg_type != RTM_NEWTFILTER || !(n->nlmsg_flags&NLM_F_CREATE))
+ if (n->nlmsg_type != RTM_NEWTFILTER ||
+ !(n->nlmsg_flags & NLM_F_CREATE))
goto errout;
} else {
switch (n->nlmsg_type) {
case RTM_NEWTFILTER:
err = -EEXIST;
- if (n->nlmsg_flags&NLM_F_EXCL)
+ if (n->nlmsg_flags & NLM_F_EXCL)
goto errout;
break;
case RTM_DELTFILTER:
@@ -314,9 +318,8 @@ errout:
return err;
}
-static int
-tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh,
- u32 pid, u32 seq, u16 flags, int event)
+static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp,
+ unsigned long fh, u32 pid, u32 seq, u16 flags, int event)
{
struct tcmsg *tcm;
struct nlmsghdr *nlh;
@@ -361,19 +364,20 @@ static int tfilter_notify(struct sk_buff
return -EINVAL;
}
- return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
+ return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC,
+ n->nlmsg_flags & NLM_F_ECHO);
}
-struct tcf_dump_args
-{
+struct tcf_dump_args {
struct tcf_walker w;
struct sk_buff *skb;
struct netlink_callback *cb;
};
-static int tcf_node_dump(struct tcf_proto *tp, unsigned long n, struct tcf_walker *arg)
+static int tcf_node_dump(struct tcf_proto *tp, unsigned long n,
+ struct tcf_walker *arg)
{
- struct tcf_dump_args *a = (void*)arg;
+ struct tcf_dump_args *a = (void *)arg;
return tcf_fill_node(a->skb, tp, n, NETLINK_CB(a->cb->skb).pid,
a->cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTFILTER);
@@ -387,7 +391,7 @@ static int tc_dump_tfilter(struct sk_buf
struct net_device *dev;
struct Qdisc *q;
struct tcf_proto *tp, **chain;
- struct tcmsg *tcm = (struct tcmsg*)NLMSG_DATA(cb->nlh);
+ struct tcmsg *tcm = (struct tcmsg *)NLMSG_DATA(cb->nlh);
unsigned long cl = 0;
const struct Qdisc_class_ops *cops;
struct tcf_dump_args arg;
@@ -431,9 +435,10 @@ static int tc_dump_tfilter(struct sk_buf
memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0]));
if (cb->args[1] == 0) {
if (tcf_fill_node(skb, tp, 0, NETLINK_CB(cb->skb).pid,
- cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTFILTER) <= 0) {
+ cb->nlh->nlmsg_seq, NLM_F_MULTI,
+ RTM_NEWTFILTER) <= 0)
break;
- }
+
cb->args[1] = 1;
}
if (tp->ops->walk == NULL)
@@ -460,8 +465,7 @@ out:
return skb->len;
}
-void
-tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts)
+void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts)
{
#ifdef CONFIG_NET_CLS_ACT
if (exts->action) {
@@ -470,10 +474,9 @@ tcf_exts_destroy(struct tcf_proto *tp, s
}
#endif
}
+EXPORT_SYMBOL(tcf_exts_destroy);
-
-int
-tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb,
+int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb,
struct rtattr *rate_tlv, struct tcf_exts *exts,
struct tcf_ext_map *map)
{
@@ -485,8 +488,9 @@ tcf_exts_validate(struct tcf_proto *tp,
struct tc_action *act;
if (map->police && tb[map->police-1]) {
- act = tcf_action_init_1(tb[map->police-1], rate_tlv, "police",
- TCA_ACT_NOREPLACE, TCA_ACT_BIND, &err);
+ act = tcf_action_init_1(tb[map->police-1], rate_tlv,
+ "police", TCA_ACT_NOREPLACE,
+ TCA_ACT_BIND, &err);
if (act == NULL)
return err;
@@ -509,10 +513,10 @@ tcf_exts_validate(struct tcf_proto *tp,
return 0;
}
+EXPORT_SYMBOL(tcf_exts_validate);
-void
-tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
- struct tcf_exts *src)
+void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
+ struct tcf_exts *src)
{
#ifdef CONFIG_NET_CLS_ACT
if (src->action) {
@@ -525,9 +529,9 @@ tcf_exts_change(struct tcf_proto *tp, st
}
#endif
}
+EXPORT_SYMBOL(tcf_exts_change);
-int
-tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
+int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
struct tcf_ext_map *map)
{
#ifdef CONFIG_NET_CLS_ACT
@@ -556,10 +560,11 @@ tcf_exts_dump(struct sk_buff *skb, struc
rtattr_failure: __attribute__ ((unused))
return -1;
}
+EXPORT_SYMBOL(tcf_exts_dump);
-int
-tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts,
- struct tcf_ext_map *map)
+
+int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts,
+ struct tcf_ext_map *map)
{
#ifdef CONFIG_NET_CLS_ACT
if (exts->action)
@@ -570,6 +575,7 @@ tcf_exts_dump_stats(struct sk_buff *skb,
rtattr_failure: __attribute__ ((unused))
return -1;
}
+EXPORT_SYMBOL(tcf_exts_dump_stats);
static int __init tc_filter_init(void)
{
@@ -582,11 +588,3 @@ static int __init tc_filter_init(void)
}
subsys_initcall(tc_filter_init);
-
-EXPORT_SYMBOL(register_tcf_proto_ops);
-EXPORT_SYMBOL(unregister_tcf_proto_ops);
-EXPORT_SYMBOL(tcf_exts_validate);
-EXPORT_SYMBOL(tcf_exts_destroy);
-EXPORT_SYMBOL(tcf_exts_change);
-EXPORT_SYMBOL(tcf_exts_dump);
-EXPORT_SYMBOL(tcf_exts_dump_stats);
--- a/net/sched/cls_tcindex.c 2008-01-20 13:33:47.000000000 -0800
+++ b/net/sched/cls_tcindex.c 2008-01-20 13:50:55.000000000 -0800
@@ -29,19 +29,6 @@
#define DEFAULT_HASH_SIZE 64 /* optimized for diffserv */
-#if 1 /* control */
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
-#if 0 /* data */
-#define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define D2PRINTK(format,args...)
-#endif
-
-
#define PRIV(tp) ((struct tcindex_data *) (tp)->root)
@@ -104,7 +91,8 @@ static int tcindex_classify(struct sk_bu
struct tcindex_filter_result *f;
int key = (skb->tc_index & p->mask) >> p->shift;
- D2PRINTK("tcindex_classify(skb %p,tp %p,res %p),p %p\n",skb,tp,res,p);
+ pr_debug("tcindex_classify(skb %p,tp %p,res %p),p %p\n",
+ skb, tp, res, p);
f = tcindex_lookup(p, key);
if (!f) {
@@ -112,11 +100,11 @@ static int tcindex_classify(struct sk_bu
return -1;
res->classid = TC_H_MAKE(TC_H_MAJ(tp->q->handle), key);
res->class = 0;
- D2PRINTK("alg 0x%x\n",res->classid);
+ pr_debug("alg 0x%x\n", res->classid);
return 0;
}
*res = f->res;
- D2PRINTK("map 0x%x\n",res->classid);
+ pr_debug("map 0x%x\n", res->classid);
return tcf_exts_exec(skb, &f->exts, res);
}
@@ -127,7 +115,7 @@ static unsigned long tcindex_get(struct
struct tcindex_data *p = PRIV(tp);
struct tcindex_filter_result *r;
- DPRINTK("tcindex_get(tp %p,handle 0x%08x)\n",tp,handle);
+ pr_debug("tcindex_get(tp %p,handle 0x%08x)\n", tp, handle);
if (p->perfect && handle >= p->alloc_hash)
return 0;
r = tcindex_lookup(p, handle);
@@ -137,7 +125,7 @@ static unsigned long tcindex_get(struct
static void tcindex_put(struct tcf_proto *tp, unsigned long f)
{
- DPRINTK("tcindex_put(tp %p,f 0x%lx)\n",tp,f);
+ pr_debug("tcindex_put(tp %p,f 0x%lx)\n", tp, f);
}
@@ -145,8 +133,8 @@ static int tcindex_init(struct tcf_proto
{
struct tcindex_data *p;
- DPRINTK("tcindex_init(tp %p)\n",tp);
- p = kzalloc(sizeof(struct tcindex_data),GFP_KERNEL);
+ pr_debug("tcindex_init(tp %p)\n", tp);
+ p = kzalloc(sizeof(struct tcindex_data), GFP_KERNEL);
if (!p)
return -ENOMEM;
@@ -166,7 +154,7 @@ __tcindex_delete(struct tcf_proto *tp, u
struct tcindex_filter_result *r = (struct tcindex_filter_result *) arg;
struct tcindex_filter *f = NULL;
- DPRINTK("tcindex_delete(tp %p,arg 0x%lx),p %p,f %p\n",tp,arg,p,f);
+ pr_debug("tcindex_delete(tp %p,arg 0x%lx),p %p,f %p\n", tp, arg, p, f);
if (p->perfect) {
if (!r->res.class)
return -ENOENT;
@@ -363,7 +351,7 @@ tcindex_change(struct tcf_proto *tp, uns
struct tcindex_data *p = PRIV(tp);
struct tcindex_filter_result *r = (struct tcindex_filter_result *) *arg;
- DPRINTK("tcindex_change(tp %p,handle 0x%08x,tca %p,arg %p),opt %p,"
+ pr_debug("tcindex_change(tp %p,handle 0x%08x,tca %p,arg %p),opt %p,"
"p %p,r %p,*arg 0x%lx\n",
tp, handle, tca, arg, opt, p, r, arg ? *arg : 0L);
@@ -380,10 +368,10 @@ tcindex_change(struct tcf_proto *tp, uns
static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker)
{
struct tcindex_data *p = PRIV(tp);
- struct tcindex_filter *f,*next;
+ struct tcindex_filter *f, *next;
int i;
- DPRINTK("tcindex_walk(tp %p,walker %p),p %p\n",tp,walker,p);
+ pr_debug("tcindex_walk(tp %p,walker %p),p %p\n", tp, walker, p);
if (p->perfect) {
for (i = 0; i < p->hash; i++) {
if (!p->perfect[i].res.class)
@@ -405,7 +393,7 @@ static void tcindex_walk(struct tcf_prot
for (f = p->h[i]; f; f = next) {
next = f->next;
if (walker->count >= walker->skip) {
- if (walker->fn(tp,(unsigned long) &f->result,
+ if (walker->fn(tp, (unsigned long) &f->result,
walker) < 0) {
walker->stop = 1;
return;
@@ -429,11 +417,11 @@ static void tcindex_destroy(struct tcf_p
struct tcindex_data *p = PRIV(tp);
struct tcf_walker walker;
- DPRINTK("tcindex_destroy(tp %p),p %p\n",tp,p);
+ pr_debug("tcindex_destroy(tp %p),p %p\n", tp, p);
walker.count = 0;
walker.skip = 0;
walker.fn = &tcindex_destroy_element;
- tcindex_walk(tp,&walker);
+ tcindex_walk(tp, &walker);
kfree(p->perfect);
kfree(p->h);
kfree(p);
@@ -449,17 +437,17 @@ static int tcindex_dump(struct tcf_proto
unsigned char *b = skb_tail_pointer(skb);
struct rtattr *rta;
- DPRINTK("tcindex_dump(tp %p,fh 0x%lx,skb %p,t %p),p %p,r %p,b %p\n",
- tp,fh,skb,t,p,r,b);
- DPRINTK("p->perfect %p p->h %p\n",p->perfect,p->h);
+ pr_debug("tcindex_dump(tp %p,fh 0x%lx,skb %p,t %p),p %p,r %p,b %p\n",
+ tp, fh, skb, t, p, r, b);
+ pr_debug("p->perfect %p p->h %p\n", p->perfect, p->h);
rta = (struct rtattr *) b;
- RTA_PUT(skb,TCA_OPTIONS,0,NULL);
+ RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
if (!fh) {
t->tcm_handle = ~0; /* whatever ... */
- RTA_PUT(skb,TCA_TCINDEX_HASH,sizeof(p->hash),&p->hash);
- RTA_PUT(skb,TCA_TCINDEX_MASK,sizeof(p->mask),&p->mask);
- RTA_PUT(skb,TCA_TCINDEX_SHIFT,sizeof(p->shift),&p->shift);
- RTA_PUT(skb,TCA_TCINDEX_FALL_THROUGH,sizeof(p->fall_through),
+ RTA_PUT(skb, TCA_TCINDEX_HASH, sizeof(p->hash), &p->hash);
+ RTA_PUT(skb, TCA_TCINDEX_MASK, sizeof(p->mask), &p->mask);
+ RTA_PUT(skb, TCA_TCINDEX_SHIFT, sizeof(p->shift), &p->shift);
+ RTA_PUT(skb, TCA_TCINDEX_FALL_THROUGH, sizeof(p->fall_through),
&p->fall_through);
rta->rta_len = skb_tail_pointer(skb) - b;
} else {
@@ -478,7 +466,7 @@ static int tcindex_dump(struct tcf_proto
}
}
}
- DPRINTK("handle = %d\n",t->tcm_handle);
+ pr_debug("handle = %d\n", t->tcm_handle);
if (r->res.class)
RTA_PUT(skb, TCA_TCINDEX_CLASSID, 4, &r->res.classid);
^ permalink raw reply
* Re: 2.6.24 regression: reference count leak in PPPoE
From: Pavel Machek @ 2008-01-20 22:59 UTC (permalink / raw)
To: Andi Kleen; +Cc: netdev, linux-kernel
In-Reply-To: <200801202053.30386.ak@suse.de>
Hi!
> My workstation running 2.6.24-rc8 just hung during shutdown with an endless
> (or rather I didn't wait more than a few minutes) loop of
>
> unregister_netdev: waiting for ppp-device to become free. Usage count = 1
>
> ppp-device was an active PPPoE device.
>
> No more information currently.
Actually, I'm getting something similar:
usb 2-2: USB disconnect, address 23
PM: Removing info for No Bus:usbdev2.23_ep83
usb0: unregister 'cdc_ether' usb-0000:00:1d.0-2, CDC Ethernet Device
PM: Removing info for No Bus:usb0
unregister_netdevice: waiting for usb0 to become free. Usage count = 1
unregister_netdevice: waiting for usb0 to become free. Usage count = 1
unregister_netdevice: waiting for usb0 to become free. Usage count = 1
unregister_netdevice: waiting for usb0 to become free. Usage count = 1
unregister_netdevice: waiting for usb0 to become free. Usage count = 1
unregister_netdevice: waiting for usb0 to become free. Usage count = 1
PM: Removing info for usb:2-2:1.0
PM: Removing info for No Bus:usbdev2.23_ep81
PM: Removing info for No Bus:usbdev2.23_ep02
The unregister_netdevice made it onto console, that means pretty
severe log level. Happened while playing with openmoko connected with
USB cable.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* [PATCH] net: add sparse annotation to ptype_seq_start/stop
From: Stephen Hemminger @ 2008-01-20 23:21 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Get rid of some more sparse warnings.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/net/core/dev.c 2008-01-20 14:25:00.000000000 -0800
+++ b/net/core/dev.c 2008-01-20 14:25:48.000000000 -0800
@@ -2543,6 +2543,7 @@ static void *ptype_get_idx(loff_t pos)
}
static void *ptype_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(rcu)
{
rcu_read_lock();
return *pos ? ptype_get_idx(*pos - 1) : SEQ_START_TOKEN;
@@ -2578,6 +2579,7 @@ found:
}
static void ptype_seq_stop(struct seq_file *seq, void *v)
+ __releases(rcu)
{
rcu_read_unlock();
}
^ permalink raw reply
* [PATCH 1/3][NET] gen_estimator: faster gen_kill_estimator
From: Jarek Poplawski @ 2008-01-20 23:46 UTC (permalink / raw)
To: netdev; +Cc: Badalian Vyacheslav, Patrick McHardy, jamal, David Miller
gen_kill_estimator() is called during qdisc_destroy() with BHs disabled,
and each time does searching for each list member. This can block soft
interrupts for quite a long time when many classes are used. This patch
changes this by storing a pointer to internal gen_estimator structures
with gnet_stats_rate_est structures used by clients of gen_estimator.
This method removes currently possibile registering in gen_estimator the
same structures more than once, but it isn't used after all. (There is
added a warning if gen_new_estimator() is called with structures being
used by gen_estimator already.)
Reported-by: Badalian Vyacheslav <slavon@bigtelecom.ru>
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
[needs more testing]
---
include/linux/gen_stats.h | 2 ++
net/core/gen_estimator.c | 36 +++++++++++++++++++++++++++++++++---
2 files changed, 35 insertions(+), 3 deletions(-)
diff -Nurp 2.6.24-rc8-mm1-/include/linux/gen_stats.h 2.6.24-rc8-mm1+/include/linux/gen_stats.h
--- 2.6.24-rc8-mm1-/include/linux/gen_stats.h 2007-10-09 22:31:38.000000000 +0200
+++ 2.6.24-rc8-mm1+/include/linux/gen_stats.h 2008-01-20 20:37:08.000000000 +0100
@@ -28,11 +28,13 @@ struct gnet_stats_basic
* struct gnet_stats_rate_est - rate estimator
* @bps: current byte rate
* @pps: current packet rate
+ * @gen_estimator: internal data
*/
struct gnet_stats_rate_est
{
__u32 bps;
__u32 pps;
+ unsigned long gen_estimator;
};
/**
diff -Nurp 2.6.24-rc8-mm1-/net/core/gen_estimator.c 2.6.24-rc8-mm1+/net/core/gen_estimator.c
--- 2.6.24-rc8-mm1-/net/core/gen_estimator.c 2008-01-19 17:54:45.000000000 +0100
+++ 2.6.24-rc8-mm1+/net/core/gen_estimator.c 2008-01-20 20:58:35.000000000 +0100
@@ -139,6 +139,9 @@ skip:
rcu_read_unlock();
}
+static void gen_kill_estimator_find(struct gnet_stats_basic *bstats,
+ struct gnet_stats_rate_est *rate_est);
+
/**
* gen_new_estimator - create a new rate estimator
* @bstats: basic statistics
@@ -171,6 +174,10 @@ int gen_new_estimator(struct gnet_stats_
if (parm->interval < -2 || parm->interval > 3)
return -EINVAL;
+ if (rate_est->gen_estimator)
+ /* not sure: not zeroed in alloc or reused */
+ gen_kill_estimator_find(bstats, rate_est);
+
est = kzalloc(sizeof(*est), GFP_KERNEL);
if (est == NULL)
return -ENOBUFS;
@@ -184,6 +191,7 @@ int gen_new_estimator(struct gnet_stats_
est->avbps = rate_est->bps<<5;
est->last_packets = bstats->packets;
est->avpps = rate_est->pps<<10;
+ rate_est->gen_estimator = (unsigned long)est;
if (!elist[idx].timer.function) {
INIT_LIST_HEAD(&elist[idx].list);
@@ -209,13 +217,30 @@ static void __gen_kill_estimator(struct
* @bstats: basic statistics
* @rate_est: rate estimator statistics
*
- * Removes the rate estimator specified by &bstats and &rate_est
- * and deletes the timer.
+ * Removes the rate estimator specified by &bstats and &rate_est.
*
* NOTE: Called under rtnl_mutex
*/
void gen_kill_estimator(struct gnet_stats_basic *bstats,
- struct gnet_stats_rate_est *rate_est)
+ struct gnet_stats_rate_est *rate_est)
+{
+ if (rate_est && rate_est->gen_estimator) {
+ struct gen_estimator *e;
+
+ e = (struct gen_estimator *)rate_est->gen_estimator;
+
+ rate_est->gen_estimator = 0;
+ write_lock_bh(&est_lock);
+ e->bstats = NULL;
+ write_unlock_bh(&est_lock);
+
+ list_del_rcu(&e->list);
+ call_rcu(&e->e_rcu, __gen_kill_estimator);
+ }
+}
+
+static void gen_kill_estimator_find(struct gnet_stats_basic *bstats,
+ struct gnet_stats_rate_est *rate_est)
{
int idx;
struct gen_estimator *e, *n;
@@ -236,6 +261,11 @@ void gen_kill_estimator(struct gnet_stat
list_del_rcu(&e->list);
call_rcu(&e->e_rcu, __gen_kill_estimator);
+
+ WARN_ON_ONCE(1); /* gen_new_estimator() repeated? */
+ rate_est->gen_estimator = 0;
+
+ return;
}
}
}
^ permalink raw reply
* [PATCH 2/3][NET] gen_estimator: list_empty() check in est_timer() fixed
From: Jarek Poplawski @ 2008-01-20 23:49 UTC (permalink / raw)
To: netdev; +Cc: Badalian Vyacheslav, Patrick McHardy, jamal, David Miller
This patch changes the method of checking for empty list in est_timer():
list_empty() is not recommended for RCU protected lists. Now, it's simply
a variable used for this.
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
---
diff -Nurp 2.6.24-rc8-mm1-p1-/net/core/gen_estimator.c 2.6.24-rc8-mm1-p1+/net/core/gen_estimator.c
--- 2.6.24-rc8-mm1-p1-/net/core/gen_estimator.c 2008-01-20 20:58:35.000000000 +0100
+++ 2.6.24-rc8-mm1-p1+/net/core/gen_estimator.c 2008-01-20 21:07:42.000000000 +0100
@@ -106,6 +106,7 @@ static void est_timer(unsigned long arg)
{
int idx = (int)arg;
struct gen_estimator *e;
+ int list_not_empty = 0;
rcu_read_lock();
list_for_each_entry_rcu(e, &elist[idx].list, list) {
@@ -118,6 +119,9 @@ static void est_timer(unsigned long arg)
if (e->bstats == NULL)
goto skip;
+ if (list_not_empty == 0)
+ list_not_empty = 1;
+
nbytes = e->bstats->bytes;
npackets = e->bstats->packets;
rate = (nbytes - e->last_bytes)<<(7 - idx);
@@ -134,7 +138,7 @@ skip:
spin_unlock(e->stats_lock);
}
- if (!list_empty(&elist[idx].list))
+ if (list_not_empty)
mod_timer(&elist[idx].timer, jiffies + ((HZ/4) << idx));
rcu_read_unlock();
}
^ permalink raw reply
* [PATCH 3/3][NET] gen_estimator: gen_replace_estimator() cosmetic changes
From: Jarek Poplawski @ 2008-01-20 23:51 UTC (permalink / raw)
To: netdev; +Cc: Badalian Vyacheslav, Patrick McHardy, jamal, David Miller
White spaces etc. are changed in gen_replace_estimator() to make it similar
to others in a file.
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
---
diff -Nurp 2.6.24-rc8-mm1-p2-/net/core/gen_estimator.c 2.6.24-rc8-mm1-p2+/net/core/gen_estimator.c
--- 2.6.24-rc8-mm1-p2-/net/core/gen_estimator.c 2008-01-20 21:07:42.000000000 +0100
+++ 2.6.24-rc8-mm1-p2+/net/core/gen_estimator.c 2008-01-20 21:15:36.000000000 +0100
@@ -275,7 +275,7 @@ static void gen_kill_estimator_find(stru
}
/**
- * gen_replace_estimator - replace rate estimator configruation
+ * gen_replace_estimator - replace rate estimator configuration
* @bstats: basic statistics
* @rate_est: rate estimator statistics
* @stats_lock: statistics lock
@@ -286,13 +286,12 @@ static void gen_kill_estimator_find(stru
*
* Returns 0 on success or a negative error code.
*/
-int
-gen_replace_estimator(struct gnet_stats_basic *bstats,
- struct gnet_stats_rate_est *rate_est, spinlock_t *stats_lock,
- struct rtattr *opt)
+int gen_replace_estimator(struct gnet_stats_basic *bstats,
+ struct gnet_stats_rate_est *rate_est,
+ spinlock_t *stats_lock, struct rtattr *opt)
{
- gen_kill_estimator(bstats, rate_est);
- return gen_new_estimator(bstats, rate_est, stats_lock, opt);
+ gen_kill_estimator(bstats, rate_est);
+ return gen_new_estimator(bstats, rate_est, stats_lock, opt);
}
^ permalink raw reply
* Re: [PATCH 2/3][NET] gen_estimator: list_empty() check in est_timer() fixed
From: Stephen Hemminger @ 2008-01-20 23:55 UTC (permalink / raw)
To: netdev
In-Reply-To: <20080120234959.GB2691@ami.dom.local>
On Mon, 21 Jan 2008 00:49:59 +0100
Jarek Poplawski <jarkao2@gmail.com> wrote:
> This patch changes the method of checking for empty list in est_timer():
> list_empty() is not recommended for RCU protected lists. Now, it's simply
> a variable used for this.
>
> Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
>
> ---
>
> diff -Nurp 2.6.24-rc8-mm1-p1-/net/core/gen_estimator.c 2.6.24-rc8-mm1-p1+/net/core/gen_estimator.c
> --- 2.6.24-rc8-mm1-p1-/net/core/gen_estimator.c 2008-01-20 20:58:35.000000000 +0100
> +++ 2.6.24-rc8-mm1-p1+/net/core/gen_estimator.c 2008-01-20 21:07:42.000000000 +0100
> @@ -106,6 +106,7 @@ static void est_timer(unsigned long arg)
> {
> int idx = (int)arg;
> struct gen_estimator *e;
> + int list_not_empty = 0;
Using a negative name for what is a boolean value leads
to code that reads like a double negative sentence. Better to choose
a variable name that is direct, can't use list_empty because that
is a macro, so how about "estimator_found".
>
> rcu_read_lock();
> list_for_each_entry_rcu(e, &elist[idx].list, list) {
> @@ -118,6 +119,9 @@ static void est_timer(unsigned long arg)
> if (e->bstats == NULL)
> goto skip;
>
> + if (list_not_empty == 0)
> + list_not_empty = 1;
> +
> nbytes = e->bstats->bytes;
> npackets = e->bstats->packets;
> rate = (nbytes - e->last_bytes)<<(7 - idx);
> @@ -134,7 +138,7 @@ skip:
> spin_unlock(e->stats_lock);
> }
>
> - if (!list_empty(&elist[idx].list))
> + if (list_not_empty)
> mod_timer(&elist[idx].timer, jiffies + ((HZ/4) << idx));
> rcu_read_unlock();
> }
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Stephen Hemminger <stephen.hemminger@vyatta.com>
^ permalink raw reply
* Re: 2.6.24 regression: reference count leak in PPPoE
From: David Miller @ 2008-01-21 0:07 UTC (permalink / raw)
To: ak; +Cc: netdev, linux-kernel
In-Reply-To: <200801202053.30386.ak@suse.de>
From: Andi Kleen <ak@suse.de>
Date: Sun, 20 Jan 2008 20:53:30 +0100
>
> My workstation running 2.6.24-rc8 just hung during shutdown with an endless
> (or rather I didn't wait more than a few minutes) loop of
>
> unregister_netdev: waiting for ppp-device to become free. Usage count = 1
>
> ppp-device was an active PPPoE device.
>
> No more information currently.
http://bugzilla.kernel.org/show_bug.cgi?id=9778
^ permalink raw reply
* Re: 2.6.24 regression: reference count leak in PPPoE
From: David Miller @ 2008-01-21 0:08 UTC (permalink / raw)
To: mingo; +Cc: ak, netdev, linux-kernel, torvalds
In-Reply-To: <20080120200109.GA31876@elte.hu>
From: Ingo Molnar <mingo@elte.hu>
Date: Sun, 20 Jan 2008 21:01:09 +0100
>
> * Andi Kleen <ak@suse.de> wrote:
>
> > My workstation running 2.6.24-rc8 just hung during shutdown with an
> > endless (or rather I didn't wait more than a few minutes) loop of
> >
> > unregister_netdev: waiting for ppp-device to become free. Usage count
> > = 1
> >
> > ppp-device was an active PPPoE device.
> >
> > No more information currently.
>
> i've seen such problems (locked up box with endless loop of usage count
> == 1) with pppoe in the past, and it seemed to be related to dynamic
> IPs. (i saw that well before 2.6.24 - reported it once to davem)
No, this is a different bug Andi is seeing and it was
recently introduced:
http://bugzilla.kernel.org/show_bug.cgi?id=9778
^ permalink raw reply
* Re: [PATCH 2/4] dsmark: get rid of trivial function
From: Patrick McHardy @ 2008-01-21 0:16 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, netdev
In-Reply-To: <20080120132550.056370c0@deepthought>
Stephen Hemminger wrote:
> Replace loop in dsmark_valid_indices with equivalent bit math.
>
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>
> --- a/net/sched/sch_dsmark.c 2008-01-20 13:07:58.000000000 -0800
> +++ b/net/sched/sch_dsmark.c 2008-01-20 13:22:54.000000000 -0800
> @@ -45,13 +45,8 @@ struct dsmark_qdisc_data {
>
> static inline int dsmark_valid_indices(u16 indices)
> {
> - while (indices != 1) {
> - if (indices & 1)
> - return 0;
> - indices >>= 1;
> - }
> -
> - return 1;
> + /* Must have only one bit set */
> + return (indices & (indices - 1)) == 0;
hweight seems easier to understand, it took me a bit
to realize that the comment matches the code :)
^ permalink raw reply
* post 2.6.24-rc7 regression: unregister_netdevice: waiting for eth1 to become free
From: Mariusz Kozlowski @ 2008-01-21 0:09 UTC (permalink / raw)
To: Andrew Morton; +Cc: davem, netdev, lkml, Jeff Garzik
[-- Attachment #1: Type: text/plain, Size: 7377 bytes --]
Hello,
I found that on current Linus tree unplugging my pcmcia wifi
card (Cabletron RoamAbout) causes part of the system to hang. I.e. mouse works
but keyboard is frozen until reboot. Actually only sysrq works but I can not
type in any terminal.
Syslog shows:
kernel: pccard: card ejected from slot 1
kernel: hermes @ 00010100: Card removed while issuing command 0x0002.
kernel: eth1: Error -19 disabling MAC port
kernel: unregister_netdevice: waiting for eth1 to become free. Usage count = 1
last message repeated 2 times
sysrq-d:
Showing all locks held in the system:
3 locks held by events/0/5:
#0: (events){--..}, at: [<c0126956>] run_workqueue+0xd2/0x1c9
#1: ((linkwatch_work).work){--..}, at: [<c012697c>] run_workqueue+0xf8/0x1c9
#2: (net_todo_run_mutex){--..}, at: [<c02d6c7a>] netdev_run_todo+0x15/0x23f
2 locks held by pccardd/1189:
#0: (&socket->skt_mutex){--..}, at: [<c0286918>] pccardd+0x129/0x227
#1: (net_todo_run_mutex){--..}, at: [<c02d6c7a>] netdev_run_todo+0x15/0x23f
1 lock held by agetty/5204:
#0: (&tty->atomic_read_lock){--..}, at: [<c022bb0f>] read_chan+0x3da/0x5bb
1 lock held by agetty/5206:
#0: (&tty->atomic_read_lock){--..}, at: [<c022bb0f>] read_chan+0x3da/0x5bb
1 lock held by agetty/5207:
#0: (&tty->atomic_read_lock){--..}, at: [<c022bb0f>] read_chan+0x3da/0x5bb
1 lock held by agetty/5208:
#0: (&tty->atomic_read_lock){--..}, at: [<c022bb0f>] read_chan+0x3da/0x5bb
1 lock held by agetty/5209:
#0: (&tty->atomic_read_lock){--..}, at: [<c022bb0f>] read_chan+0x3da/0x5bb
1 lock held by ifconfig/5581:
#0: (net_todo_run_mutex){--..}, at: [<c02d6c7a>] netdev_run_todo+0x15/0x23f
sysrq-w:
SysRq : Show Blocked State
task PC stack pid father
events/0 D dcd62780 0 5 2
dd834ee0 00000096 c033f2e0 dcd62780 00000000 c043f500 00000246 dd846000
dd834f28 c033547a 00000000 00000002 c02d6c7a dd834f0c c043f538 c043f524
c02d6c7a 00000000 dcfa5e54 c043f524 dd846000 c043f500 dd834f08 c043f744
Call Trace:
[<c033547a>] mutex_lock_nested+0xe6/0x306
[<c02d6c7a>] netdev_run_todo+0x15/0x23f
[<c02de559>] rtnl_unlock+0x12/0x14
[<c02df907>] linkwatch_event+0x25/0x27
[<c01269a4>] run_workqueue+0x120/0x1c9
[<c01272f6>] worker_thread+0x71/0xab
[<c0129dbd>] kthread+0x36/0x58
[<c0103507>] kernel_thread_helper+0x7/0x10
=======================
pccardd D dccaaa00 0 1189 2
dce33e00 00000096 c033f260 dccaaa00 00000282 dce33e10 ffff4f93 ffff4f53
dce33e30 c0334b38 c043f6c0 dce33e30 c04dc740 c04dc740 ffff4f93 c01202e9
dce16000 c04dc280 dcc09060 ffff4811 dce33e38 c0334bab dce33e40 c01207ae
Call Trace:
[<c0334b38>] schedule_timeout+0x43/0xa2
[<c0334bab>] schedule_timeout_uninterruptible+0x14/0x16
[<c01207ae>] msleep+0x12/0x18
[<c02d6d2e>] netdev_run_todo+0xc9/0x23f
[<c02de559>] rtnl_unlock+0x12/0x14
[<c02d54ad>] unregister_netdev+0x17/0x1b
[<ded1c111>] orinoco_cs_detach+0x1b/0x2d [orinoco_cs]
[<ded0873b>] pcmcia_device_remove+0x37/0xc6 [pcmcia]
[<c0258080>] __device_release_driver+0x6a/0x92
[<c0258493>] device_release_driver+0x2f/0x45
[<c025798f>] bus_remove_device+0x53/0x75
[<c0256194>] device_del+0x146/0x257
[<c02562b0>] device_unregister+0xb/0x15
[<ded08683>] pcmcia_card_remove+0x71/0x87 [pcmcia]
[<ded091ec>] ds_event+0x54/0x99 [pcmcia]
[<c0285f5a>] send_event+0x78/0xa4
[<c0286175>] socket_remove_drivers+0x12/0x14
[<c0286185>] socket_shutdown+0xe/0xc7
[<c0286264>] socket_remove+0x26/0x2c
[<c02869e7>] pccardd+0x1f8/0x227
[<c0129dbd>] kthread+0x36/0x58
[<c0103507>] kernel_thread_helper+0x7/0x10
=======================
ifconfig D ddb5ea00 0 5581 5580
dcfa5e2c 00000096 c033f2e0 ddb5ea00 00000000 c043f500 00000246 dce94000
dcfa5e74 c033547a 00000000 00000002 c02d6c7a dce9456c c043f538 c043f524
c02d6c7a 00000000 c043f524 dd834f08 dce94000 c043f500 dcfa5e54 00000000
Call Trace:
[<c033547a>] mutex_lock_nested+0xe6/0x306
[<c02d6c7a>] netdev_run_todo+0x15/0x23f
[<c02de559>] rtnl_unlock+0x12/0x14
[<c02d614c>] dev_ioctl+0x165/0x4f5
[<c02c9967>] sock_ioctl+0xe2/0x211
[<c016e3c2>] do_ioctl+0x22/0x71
[<c016e466>] vfs_ioctl+0x55/0x28a
[<c016e6ce>] sys_ioctl+0x33/0x51
[<c01028ca>] sysenter_past_esp+0x5f/0xa5
=======================
I run bisection three times but it doesn't give a clear answer which commit is the culprit.
First bisection: current Linus bad - v2.6.23 good. First bad commit:
ecd2ebdea350c40e73c00d400d74c8a09c072082 is first bad commit
commit ecd2ebdea350c40e73c00d400d74c8a09c072082
Author: Jarek Poplawski <jarkao2@gmail.com>
Date: Thu Jan 10 21:21:20 2008 -0800
[AX25] af_ax25: Possible circular locking.
Which is bogus because I don't even have ax25 compiled into the kernel.
Next two (to be sure) times I run bisection: current Linus bad - v2.6.24-rc7 good.
Two times I got the same result, first bad commit:
9cd40029423701c376391da59d2c6469672b4bed is first bad commit
commit 9cd40029423701c376391da59d2c6469672b4bed
Author: Pavel Emelyanov <xemul@openvz.org>
Date: Thu Jan 10 03:48:38 2008 -0800
[NEIGH]: Fix race between neigh_parms_release and neightbl_fill_parms
But this also seems wrong. When I apply this patch the problem doesn't show.
Good thing is that both commits are very close to each other so I guess the culprit
is somewhere there near to them. All I can say for sure now is that v2.6.24-rc7 is good
and current Linus is bad.
Box is x86 32bit. Config is attached. If I can provide you with any more info just let me know.
My plan is to apply patches, one at a time, starting from 9cd4002942 and see what happens
unless someone knows already which one is bad.
Regards,
Mariusz
This is the last bisection log:
git-bisect start
# bad: [a7da60f41551abb3c520b03d42ec05dd7decfc7f] Remove bogus duplicate CONFIG_LGUEST_GUEST entry.
git-bisect bad a7da60f41551abb3c520b03d42ec05dd7decfc7f
# good: [3ce54450461bad18bbe1f9f5aa3ecd2f8e8d1235] Linux 2.6.24-rc7
git-bisect good 3ce54450461bad18bbe1f9f5aa3ecd2f8e8d1235
# good: [d72ec9e20e4de995aa957f171cf84b136689e4c0] Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
git-bisect good d72ec9e20e4de995aa957f171cf84b136689e4c0
# bad: [0938e7586440ac97cedc0f5528a8684ebfa4ce43] Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
git-bisect bad 0938e7586440ac97cedc0f5528a8684ebfa4ce43
# good: [d8cf5389bd9d1f0ac9fea51796c274ba64b83d80] libata: relocate sdev->manage_start_stop configuration
git-bisect good d8cf5389bd9d1f0ac9fea51796c274ba64b83d80
# bad: [1b310fca30ac9851f79337ca72b1cf6a0f58064a] [TOKENRING]: rif_timer not initialized properly
git-bisect bad 1b310fca30ac9851f79337ca72b1cf6a0f58064a
# bad: [5c5482266537fdb24d6b8462540d8f65a6007a97] [BLUETOOTH]: Always send explicit hci_ll wake-up acks.
git-bisect bad 5c5482266537fdb24d6b8462540d8f65a6007a97
# bad: [0bcceadceb0907094ba4e40bf9a7cd9b080f13fb] [IPV4] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache
git-bisect bad 0bcceadceb0907094ba4e40bf9a7cd9b080f13fb
# bad: [9cd40029423701c376391da59d2c6469672b4bed] [NEIGH]: Fix race between neigh_parms_release and neightbl_fill_parms
git-bisect bad 9cd40029423701c376391da59d2c6469672b4bed
# good: [b0de8e402dc5d3ee04f4d0f669ae492a3e569933] [NIU]: Support for Marvell PHY
git-bisect good b0de8e402dc5d3ee04f4d0f669ae492a3e569933
[-- Attachment #2: config.gz --]
[-- Type: application/x-gzip, Size: 9827 bytes --]
^ permalink raw reply
* Re: post 2.6.24-rc7 regression: unregister_netdevice: waiting for eth1 to become free
From: David Miller @ 2008-01-21 0:32 UTC (permalink / raw)
To: m.kozlowski; +Cc: akpm, netdev, linux-kernel, jgarzik
In-Reply-To: <200801210109.42153.m.kozlowski@tuxland.pl>
From: Mariusz Kozlowski <m.kozlowski@tuxland.pl>
Date: Mon, 21 Jan 2008 01:09:41 +0100
> kernel: unregister_netdevice: waiting for eth1 to become free. Usage count = 1
Known problem:
http://bugzilla.kernel.org/show_bug.cgi?id=9778
^ permalink raw reply
* Re: [2.6 patch] atm/idt77105.c: fix section mismatch
From: Roel Kluin @ 2008-01-21 0:37 UTC (permalink / raw)
To: Adrian Bunk; +Cc: chas, jgarzik, netdev, linux-kernel
In-Reply-To: <20080119131849.GA8669@does.not.exist>
Adrian Bunk wrote:
> EXPORT_SYMBOL'ed code mustn't be __*init.
>
Is it correct that the cases below are section mismatches as well?
If required I'll send separate patches to the respective maintainers
& lists.
__init
arch/arm/mach-imx/generic.c:330:EXPORT_SYMBOL(set_imx_fb_info);
__devinit
arch/parisc/kernel/pci.c:245:EXPORT_SYMBOL(pcibios_resource_to_bus);
arch/powerpc/kernel/pci_64.c:371:EXPORT_SYMBOL(of_scan_bus);
arch/powerpc/kernel/pci_64.c:460:EXPORT_SYMBOL(of_scan_pci_bridge);
arch/powerpc/kernel/pci_64.c:842:EXPORT_SYMBOL(pcibios_fixup_device_resources);
arch/powerpc/kernel/pci_64.c:862:EXPORT_SYMBOL(pcibios_setup_new_device);
arch/powerpc/kernel/pci_64.c:908:EXPORT_SYMBOL(pcibios_fixup_bus);
arch/ia64/pci/pci.c:477:EXPORT_SYMBOL_GPL(pcibios_fixup_device_resources);
arch/powerpc/kernel/vio.c:240:EXPORT_SYMBOL(vio_register_device_node);
arch/powerpc/kernel/vio.c:309:EXPORT_SYMBOL(vio_unregister_device);
__cpu_init
arch/x86/kernel/topology.c:60:EXPORT_SYMBOL(arch_register_cpu);
--
EXPORT_SYMBOL'ed code mustn't be __*init.
Signed-off-by: Roel Kluin <12o3l@tiscali.nl>
---
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c
index 4cfc9d3..92e098a 100644
--- a/arch/arm/mach-imx/generic.c
+++ b/arch/arm/mach-imx/generic.c
@@ -323,7 +323,7 @@ void __init imx_set_mmc_info(struct imxmmc_platform_data *info)
static struct imxfb_mach_info imx_fb_info;
-void __init set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info)
+void set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info)
{
memcpy(&imx_fb_info,hard_imx_fb_info,sizeof(struct imxfb_mach_info));
}
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 488e48a..8c200a8 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -470,7 +470,7 @@ pcibios_fixup_resources(struct pci_dev *dev, int start, int limit)
}
}
-void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
+void pcibios_fixup_device_resources(struct pci_dev *dev)
{
pcibios_fixup_resources(dev, 0, PCI_BRIDGE_RESOURCES);
}
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
index 507d0ac..9cf3cfc 100644
--- a/arch/parisc/kernel/pci.c
+++ b/arch/parisc/kernel/pci.c
@@ -195,7 +195,7 @@ void __init pcibios_init_bus(struct pci_bus *bus)
}
/* called by drivers/pci/setup-bus.c:pci_setup_bridge(). */
-void __devinit pcibios_resource_to_bus(struct pci_dev *dev,
+void pcibios_resource_to_bus(struct pci_dev *dev,
struct pci_bus_region *region, struct resource *res)
{
#ifdef CONFIG_64BIT
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 9f63bdc..5f1151a 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -338,7 +338,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
}
EXPORT_SYMBOL(of_create_pci_dev);
-void __devinit of_scan_bus(struct device_node *node,
+void of_scan_bus(struct device_node *node,
struct pci_bus *bus)
{
struct device_node *child = NULL;
@@ -370,7 +370,7 @@ void __devinit of_scan_bus(struct device_node *node,
}
EXPORT_SYMBOL(of_scan_bus);
-void __devinit of_scan_pci_bridge(struct device_node *node,
+void of_scan_pci_bridge(struct device_node *node,
struct pci_dev *dev)
{
struct pci_bus *bus;
@@ -818,7 +818,7 @@ static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
}
}
-void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
+void pcibios_fixup_device_resources(struct pci_dev *dev,
struct pci_bus *bus)
{
/* Update device resources. */
@@ -841,7 +841,7 @@ void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
}
EXPORT_SYMBOL(pcibios_fixup_device_resources);
-void __devinit pcibios_setup_new_device(struct pci_dev *dev)
+void pcibios_setup_new_device(struct pci_dev *dev)
{
struct dev_archdata *sd = &dev->dev.archdata;
@@ -879,7 +879,7 @@ static void __devinit do_bus_setup(struct pci_bus *bus)
}
}
-void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+void pcibios_fixup_bus(struct pci_bus *bus)
{
struct pci_dev *dev = bus->self;
struct device_node *np;
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 19a5656..70a2ce4 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -178,7 +178,7 @@ static void __devinit vio_dev_release(struct device *dev)
* Returns a pointer to the created vio_dev or NULL if node has
* NULL device_type or compatible fields.
*/
-struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
+struct vio_dev * vio_register_device_node(struct device_node *of_node)
{
struct vio_dev *viodev;
const unsigned int *unit_address;
@@ -302,7 +302,7 @@ static struct device_attribute vio_dev_attrs[] = {
__ATTR_NULL
};
-void __devinit vio_unregister_device(struct vio_dev *viodev)
+void vio_unregister_device(struct vio_dev *viodev)
{
device_unregister(&viodev->dev);
}
diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
index 7e16d67..561acc0 100644
--- a/arch/x86/kernel/topology.c
+++ b/arch/x86/kernel/topology.c
@@ -33,7 +33,7 @@
static struct i386_cpu cpu_devices[NR_CPUS];
-int __cpuinit arch_register_cpu(int num)
+int arch_register_cpu(int num)
{
/*
* CPU0 cannot be offlined due to several
^ permalink raw reply related
* Re: 2.6.24 regression: reference count leak in PPPoE
From: nigel @ 2008-01-21 0:33 UTC (permalink / raw)
To: Ingo Molnar; +Cc: Andi Kleen, netdev, linux-kernel, Linus Torvalds
In-Reply-To: <20080120200109.GA31876@elte.hu>
Hi.
Quoting Ingo Molnar <mingo@elte.hu>:
>
> * Andi Kleen <ak@suse.de> wrote:
>
>> My workstation running 2.6.24-rc8 just hung during shutdown with an
>> endless (or rather I didn't wait more than a few minutes) loop of
>>
>> unregister_netdev: waiting for ppp-device to become free. Usage count
>> = 1
>>
>> ppp-device was an active PPPoE device.
>>
>> No more information currently.
>
> i've seen such problems (locked up box with endless loop of usage count
> == 1) with pppoe in the past, and it seemed to be related to dynamic
> IPs. (i saw that well before 2.6.24 - reported it once to davem)
>
> It seems to have stopped when i stopped using ipsec and started using
> vpnc. (but no firm info - this was sporadic - happened every few months
> or so) Are you using ipsec and dynamic IPs by any chance?
This isn't PPPoE specific. It has also been seen with e1000, madwifi
and an intel based card. It was introduced by a Jan 10 commit post rc7
(sorry, don't have the details right now - my laptop died yesterday).
A bugzilla has already been opened.
Nigel
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.
^ permalink raw reply
* Re: [PATCH 0/3 net-2.6.25] call FIB rule->action in the correct namespace
From: David Miller @ 2008-01-21 0:47 UTC (permalink / raw)
To: den; +Cc: dlezcano, netdev, containers, devel
In-Reply-To: <478F2933.1000007@openvz.org>
From: "Denis V. Lunev" <den@openvz.org>
Date: Thu, 17 Jan 2008 13:08:51 +0300
> FIB rule->action should operate in the same namespace as fib_lookup.
> This is definitely missed right now.
>
> There are two ways to implement this: pass struct net into another rules
> API call (2 levels) or place netns into rule struct directly. The second
> approach seems better as the code will grow less.
>
> Additionally, the patchset cleanups struct net from
> fib_rules_register/unregister to have network namespace context at the
> time of default rules creation.
>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
All 3 patches applied, thanks.
^ permalink raw reply
* Re: [patch for 2.6.24? 1/1] bonding: locking fix
From: David Miller @ 2008-01-21 0:57 UTC (permalink / raw)
To: akpm; +Cc: fubar, olel, jeff, shemminger, netdev
In-Reply-To: <20080117154243.9ee4265c.akpm@linux-foundation.org>
From: Andrew Morton <akpm@linux-foundation.org>
Date: Thu, 17 Jan 2008 15:42:43 -0800
> Applying this:
>
> --- a/drivers/net/bonding/bond_sysfs.c~bonding-locking-fix
> +++ a/drivers/net/bonding/bond_sysfs.c
> @@ -1111,8 +1111,6 @@ static ssize_t bonding_store_primary(str
> out:
> write_unlock_bh(&bond->lock);
>
> - rtnl_unlock();
> -
> return count;
> }
> static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary);
>
>
> is better than doing nothing.
If you look at the change that introduced this:
commit 6603a6f25e4bca922a7dfbf0bf03072d98850176
Author: Jay Vosburgh <fubar@us.ibm.com>
Date: Wed Oct 17 17:37:50 2007 -0700
bonding: Convert more locks to _bh, acquire rtnl, for new locking
Convert more lock acquisitions to _bh flavor to avoid deadlock
with workqueue activity and add acquisition of RTNL in appropriate places.
Affects ALB mode, as well as core bonding functions and sysfs.
Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
It is clearly the author's intent to surround the execution
of this function (and also bonding_show_active_slave() which
was done correctly) with RTNL semaphore holding.
Therefore the correct fix, which I'll push, is:
commit 991a15cb1cd60a918bd864bb79e7649c30aab275
Author: David S. Miller <davem@davemloft.net>
Date: Sun Jan 20 16:55:20 2008 -0800
[BONDING]: Fix rtnl locking in bonding_store_primary().
Changeset 6603a6f25e4bca922a7dfbf0bf03072d98850176 (Convert more locks
to _bh, acquire rtnl, for new locking) added a regression.
A rtnl_unlock() was added but a rtnl_lock() was not.
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 11b76b3..4845c01 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1075,6 +1075,7 @@ static ssize_t bonding_store_primary(struct device *d,
struct slave *slave;
struct bonding *bond = to_bond(d);
+ rtnl_lock();
write_lock_bh(&bond->lock);
if (!USES_PRIMARY(bond->params.mode)) {
printk(KERN_INFO DRV_NAME
^ permalink raw reply related
* Re: [PATCH] [IrDA] af_irda memory leak fixes
From: David Miller @ 2008-01-21 0:58 UTC (permalink / raw)
To: samuel-jcdQHdrhKHMdnm+yROfE0A
Cc: irda-users-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
jesper.juhl-Re5JQEeQqe8AvxtiuMwx3w, netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20080118075322.GB3063-jcdQHdrhKHMdnm+yROfE0A@public.gmane.org>
From: Samuel Ortiz <samuel-jcdQHdrhKHMdnm+yROfE0A@public.gmane.org>
Date: Fri, 18 Jan 2008 08:53:22 +0100
> Hi Dave,
>
> Here goes an IrDA patch against your latest net-2.6 tree.
>
> This patch fixes some af_irda memory leaks.
> It also checks for irias_new_obect() return value.
>
> Signed-off-by: Jesper Juhl <jesper.juhl-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Samuel Ortiz <samuel-jcdQHdrhKHMdnm+yROfE0A@public.gmane.org>
Applied, thanks Sam.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
^ permalink raw reply
* Re: [PATCH 0/7] bonding: 7 fixes for 2.6.24
From: David Miller @ 2008-01-21 1:15 UTC (permalink / raw)
To: fubar; +Cc: netdev, jgarzik, andy, akpm
In-Reply-To: <12006159033257-git-send-email-fubar@us.ibm.com>
From: Jay Vosburgh <fubar@us.ibm.com>
Date: Thu, 17 Jan 2008 16:24:56 -0800
> Following are seven patches to fix locking problems,
> silence locking-related warnings and resolve one recent regression
> in the current 2.6.24-rc.
Jeff, are you going to merge this stuff in?
I'll drop that rtnl_lock() one-liner if so...
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox