* [v4 PATCH 4/6] IPVS: rename of netns init and cleanup functions.
From: Hans Schillstrom @ 2011-05-01 16:50 UTC (permalink / raw)
To: ja, horms, ebiederm, lvs-devel, netdev, netfilter-devel
Cc: hans.schillstrom, Hans Schillstrom
In-Reply-To: <1304268618-18103-1-git-send-email-hans@schillstrom.com>
Make it more clear what the functions does,
on request by Julian.
Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
Signed-off-by: Hans Schillstrom <hans@schillstrom.com>
---
include/net/ip_vs.h | 26 +++++++++++++-------------
net/netfilter/ipvs/ip_vs_app.c | 4 ++--
net/netfilter/ipvs/ip_vs_conn.c | 4 ++--
net/netfilter/ipvs/ip_vs_core.c | 36 ++++++++++++++++++------------------
net/netfilter/ipvs/ip_vs_ctl.c | 20 ++++++++++----------
net/netfilter/ipvs/ip_vs_est.c | 4 ++--
net/netfilter/ipvs/ip_vs_proto.c | 4 ++--
net/netfilter/ipvs/ip_vs_sync.c | 4 ++--
8 files changed, 51 insertions(+), 51 deletions(-)
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 86aefed..da2aea9 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -1093,19 +1093,19 @@ ip_vs_control_add(struct ip_vs_conn *cp, struct ip_vs_conn *ctl_cp)
/*
* IPVS netns init & cleanup functions
*/
-extern int __ip_vs_estimator_init(struct net *net);
-extern int __ip_vs_control_init(struct net *net);
-extern int __ip_vs_protocol_init(struct net *net);
-extern int __ip_vs_app_init(struct net *net);
-extern int __ip_vs_conn_init(struct net *net);
-extern int __ip_vs_sync_init(struct net *net);
-extern void __ip_vs_conn_cleanup(struct net *net);
-extern void __ip_vs_app_cleanup(struct net *net);
-extern void __ip_vs_protocol_cleanup(struct net *net);
-extern void __ip_vs_control_cleanup(struct net *net);
-extern void __ip_vs_estimator_cleanup(struct net *net);
-extern void __ip_vs_sync_cleanup(struct net *net);
-extern void __ip_vs_service_cleanup(struct net *net);
+extern int ip_vs_estimator_net_init(struct net *net);
+extern int ip_vs_control_net_init(struct net *net);
+extern int ip_vs_protocol_net_init(struct net *net);
+extern int ip_vs_app_net_init(struct net *net);
+extern int ip_vs_conn_net_init(struct net *net);
+extern int ip_vs_sync_net_init(struct net *net);
+extern void ip_vs_conn_net_cleanup(struct net *net);
+extern void ip_vs_app_net_cleanup(struct net *net);
+extern void ip_vs_protocol_net_cleanup(struct net *net);
+extern void ip_vs_control_net_cleanup(struct net *net);
+extern void ip_vs_estimator_net_cleanup(struct net *net);
+extern void ip_vs_sync_net_cleanup(struct net *net);
+extern void ip_vs_service_net_cleanup(struct net *net);
/*
* IPVS application functions
diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
index 51f3af7..81b299d 100644
--- a/net/netfilter/ipvs/ip_vs_app.c
+++ b/net/netfilter/ipvs/ip_vs_app.c
@@ -576,7 +576,7 @@ static const struct file_operations ip_vs_app_fops = {
};
#endif
-int __net_init __ip_vs_app_init(struct net *net)
+int __net_init ip_vs_app_net_init(struct net *net)
{
struct netns_ipvs *ipvs = net_ipvs(net);
@@ -585,7 +585,7 @@ int __net_init __ip_vs_app_init(struct net *net)
return 0;
}
-void __net_exit __ip_vs_app_cleanup(struct net *net)
+void __net_exit ip_vs_app_net_cleanup(struct net *net)
{
proc_net_remove(net, "ip_vs_app");
}
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index d3fd91b..b1e7a0c 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -1247,7 +1247,7 @@ flush_again:
/*
* per netns init and exit
*/
-int __net_init __ip_vs_conn_init(struct net *net)
+int __net_init ip_vs_conn_net_init(struct net *net)
{
struct netns_ipvs *ipvs = net_ipvs(net);
@@ -1258,7 +1258,7 @@ int __net_init __ip_vs_conn_init(struct net *net)
return 0;
}
-void __net_exit __ip_vs_conn_cleanup(struct net *net)
+void __net_exit ip_vs_conn_net_cleanup(struct net *net)
{
/* flush all the connection entries first */
ip_vs_conn_flush(net);
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index b9debc9..4582716 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -1911,22 +1911,22 @@ static int __net_init __ip_vs_init(struct net *net)
atomic_inc(&ipvs_netns_cnt);
net->ipvs = ipvs;
- if (__ip_vs_estimator_init(net) < 0)
+ if (ip_vs_estimator_net_init(net) < 0)
goto estimator_fail;
- if (__ip_vs_control_init(net) < 0)
+ if (ip_vs_control_net_init(net) < 0)
goto control_fail;
- if (__ip_vs_protocol_init(net) < 0)
+ if (ip_vs_protocol_net_init(net) < 0)
goto protocol_fail;
- if (__ip_vs_app_init(net) < 0)
+ if (ip_vs_app_net_init(net) < 0)
goto app_fail;
- if (__ip_vs_conn_init(net) < 0)
+ if (ip_vs_conn_net_init(net) < 0)
goto conn_fail;
- if (__ip_vs_sync_init(net) < 0)
+ if (ip_vs_sync_net_init(net) < 0)
goto sync_fail;
printk(KERN_INFO "IPVS: Creating netns size=%zu id=%d\n",
@@ -1937,27 +1937,27 @@ static int __net_init __ip_vs_init(struct net *net)
*/
sync_fail:
- __ip_vs_conn_cleanup(net);
+ ip_vs_conn_net_cleanup(net);
conn_fail:
- __ip_vs_app_cleanup(net);
+ ip_vs_app_net_cleanup(net);
app_fail:
- __ip_vs_protocol_cleanup(net);
+ ip_vs_protocol_net_cleanup(net);
protocol_fail:
- __ip_vs_control_cleanup(net);
+ ip_vs_control_net_cleanup(net);
control_fail:
- __ip_vs_estimator_cleanup(net);
+ ip_vs_estimator_net_cleanup(net);
estimator_fail:
return -ENOMEM;
}
static void __net_exit __ip_vs_cleanup(struct net *net)
{
- __ip_vs_service_cleanup(net); /* ip_vs_flush() with locks */
- __ip_vs_conn_cleanup(net);
- __ip_vs_app_cleanup(net);
- __ip_vs_protocol_cleanup(net);
- __ip_vs_control_cleanup(net);
- __ip_vs_estimator_cleanup(net);
+ ip_vs_service_net_cleanup(net); /* ip_vs_flush() with locks */
+ ip_vs_conn_net_cleanup(net);
+ ip_vs_app_net_cleanup(net);
+ ip_vs_protocol_net_cleanup(net);
+ ip_vs_control_net_cleanup(net);
+ ip_vs_estimator_net_cleanup(net);
IP_VS_DBG(2, "ipvs netns %d released\n", net_ipvs(net)->gen);
}
@@ -1965,7 +1965,7 @@ static void __net_exit __ip_vs_dev_cleanup(struct net *net)
{
EnterFunction(2);
net_ipvs(net)->enable = 0; /* Disable packet reception */
- __ip_vs_sync_cleanup(net);
+ ip_vs_sync_net_cleanup(net);
LeaveFunction(2);
}
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index fe8891f..9074c5d 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -1486,7 +1486,7 @@ static int ip_vs_flush(struct net *net)
* Delete service by {netns} in the service table.
* Called by __ip_vs_cleanup()
*/
-void __ip_vs_service_cleanup(struct net *net)
+void ip_vs_service_net_cleanup(struct net *net)
{
EnterFunction(2);
/* Check for "full" addressed entries */
@@ -1665,7 +1665,7 @@ proc_do_sync_mode(ctl_table *table, int write,
/*
* IPVS sysctl table (under the /proc/sys/net/ipv4/vs/)
* Do not change order or insert new entries without
- * align with netns init in __ip_vs_control_init()
+ * align with netns init in ip_vs_control_net_init()
*/
static struct ctl_table vs_vars[] = {
@@ -3601,7 +3601,7 @@ static void ip_vs_genl_unregister(void)
* per netns intit/exit func.
*/
#ifdef CONFIG_SYSCTL
-int __net_init __ip_vs_control_init_sysctl(struct net *net)
+int __net_init ip_vs_control_net_init_sysctl(struct net *net)
{
int idx;
struct netns_ipvs *ipvs = net_ipvs(net);
@@ -3660,7 +3660,7 @@ int __net_init __ip_vs_control_init_sysctl(struct net *net)
return 0;
}
-void __net_init __ip_vs_control_cleanup_sysctl(struct net *net)
+void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net)
{
struct netns_ipvs *ipvs = net_ipvs(net);
@@ -3671,8 +3671,8 @@ void __net_init __ip_vs_control_cleanup_sysctl(struct net *net)
#else
-int __net_init __ip_vs_control_init_sysctl(struct net *net) { return 0; }
-void __net_init __ip_vs_control_cleanup_sysctl(struct net *net) { }
+int __net_init ip_vs_control_net_init_sysctl(struct net *net) { return 0; }
+void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net) { }
#endif
@@ -3680,7 +3680,7 @@ static struct notifier_block ip_vs_dst_notifier = {
.notifier_call = ip_vs_dst_event,
};
-int __net_init __ip_vs_control_init(struct net *net)
+int __net_init ip_vs_control_net_init(struct net *net)
{
int idx;
struct netns_ipvs *ipvs = net_ipvs(net);
@@ -3708,7 +3708,7 @@ int __net_init __ip_vs_control_init(struct net *net)
proc_net_fops_create(net, "ip_vs_stats_percpu", 0,
&ip_vs_stats_percpu_fops);
- if (__ip_vs_control_init_sysctl(net))
+ if (ip_vs_control_net_init_sysctl(net))
goto err;
return 0;
@@ -3718,13 +3718,13 @@ err:
return -ENOMEM;
}
-void __net_exit __ip_vs_control_cleanup(struct net *net)
+void __net_exit ip_vs_control_net_cleanup(struct net *net)
{
struct netns_ipvs *ipvs = net_ipvs(net);
ip_vs_trash_cleanup(net);
ip_vs_stop_estimator(net, &ipvs->tot_stats);
- __ip_vs_control_cleanup_sysctl(net);
+ ip_vs_control_net_cleanup_sysctl(net);
proc_net_remove(net, "ip_vs_stats_percpu");
proc_net_remove(net, "ip_vs_stats");
proc_net_remove(net, "ip_vs");
diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c
index 508cce9..f5d2a01 100644
--- a/net/netfilter/ipvs/ip_vs_est.c
+++ b/net/netfilter/ipvs/ip_vs_est.c
@@ -192,7 +192,7 @@ void ip_vs_read_estimator(struct ip_vs_stats_user *dst,
dst->outbps = (e->outbps + 0xF) >> 5;
}
-int __net_init __ip_vs_estimator_init(struct net *net)
+int __net_init ip_vs_estimator_net_init(struct net *net)
{
struct netns_ipvs *ipvs = net_ipvs(net);
@@ -203,7 +203,7 @@ int __net_init __ip_vs_estimator_init(struct net *net)
return 0;
}
-void __net_exit __ip_vs_estimator_cleanup(struct net *net)
+void __net_exit ip_vs_estimator_net_cleanup(struct net *net)
{
del_timer_sync(&net_ipvs(net)->est_timer);
}
diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
index eb86028..52d073c 100644
--- a/net/netfilter/ipvs/ip_vs_proto.c
+++ b/net/netfilter/ipvs/ip_vs_proto.c
@@ -316,7 +316,7 @@ ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp,
/*
* per network name-space init
*/
-int __net_init __ip_vs_protocol_init(struct net *net)
+int __net_init ip_vs_protocol_net_init(struct net *net)
{
#ifdef CONFIG_IP_VS_PROTO_TCP
register_ip_vs_proto_netns(net, &ip_vs_protocol_tcp);
@@ -336,7 +336,7 @@ int __net_init __ip_vs_protocol_init(struct net *net)
return 0;
}
-void __net_exit __ip_vs_protocol_cleanup(struct net *net)
+void __net_exit ip_vs_protocol_net_cleanup(struct net *net)
{
struct netns_ipvs *ipvs = net_ipvs(net);
struct ip_vs_proto_data *pd;
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index e292e5b..58bfabb 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -1663,7 +1663,7 @@ int stop_sync_thread(struct net *net, int state)
/*
* Initialize data struct for each netns
*/
-int __net_init __ip_vs_sync_init(struct net *net)
+int __net_init ip_vs_sync_net_init(struct net *net)
{
struct netns_ipvs *ipvs = net_ipvs(net);
@@ -1677,7 +1677,7 @@ int __net_init __ip_vs_sync_init(struct net *net)
return 0;
}
-void __ip_vs_sync_cleanup(struct net *net)
+void ip_vs_sync_net_cleanup(struct net *net)
{
int retc;
--
1.7.2.3
^ permalink raw reply related
* [v4 PATCH 5/6] IPVS: remove unused init and cleanup functions.
From: Hans Schillstrom @ 2011-05-01 16:50 UTC (permalink / raw)
To: ja, horms, ebiederm, lvs-devel, netdev, netfilter-devel
Cc: hans.schillstrom, Hans Schillstrom
In-Reply-To: <1304268618-18103-1-git-send-email-hans@schillstrom.com>
After restructuring, there is some unused or empty functions
left to be removed.
Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
Signed-off-by: Hans Schillstrom <hans@schillstrom.com>
---
include/net/ip_vs.h | 6 ------
net/netfilter/ipvs/ip_vs_app.c | 10 ----------
net/netfilter/ipvs/ip_vs_core.c | 29 ++++-------------------------
net/netfilter/ipvs/ip_vs_est.c | 9 ---------
net/netfilter/ipvs/ip_vs_sync.c | 9 ---------
5 files changed, 4 insertions(+), 59 deletions(-)
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index da2aea9..10417ab 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -1123,8 +1123,6 @@ extern void ip_vs_app_inc_put(struct ip_vs_app *inc);
extern int ip_vs_app_pkt_out(struct ip_vs_conn *, struct sk_buff *skb);
extern int ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff *skb);
-extern int ip_vs_app_init(void);
-extern void ip_vs_app_cleanup(void);
void ip_vs_bind_pe(struct ip_vs_service *svc, struct ip_vs_pe *pe);
void ip_vs_unbind_pe(struct ip_vs_service *svc);
@@ -1227,15 +1225,11 @@ extern int start_sync_thread(struct net *net, int state, char *mcast_ifn,
__u8 syncid);
extern int stop_sync_thread(struct net *net, int state);
extern void ip_vs_sync_conn(struct net *net, struct ip_vs_conn *cp);
-extern int ip_vs_sync_init(void);
-extern void ip_vs_sync_cleanup(void);
/*
* IPVS rate estimator prototypes (from ip_vs_est.c)
*/
-extern int ip_vs_estimator_init(void);
-extern void ip_vs_estimator_cleanup(void);
extern void ip_vs_start_estimator(struct net *net, struct ip_vs_stats *stats);
extern void ip_vs_stop_estimator(struct net *net, struct ip_vs_stats *stats);
extern void ip_vs_zero_estimator(struct ip_vs_stats *stats);
diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
index 81b299d..5f34cf4 100644
--- a/net/netfilter/ipvs/ip_vs_app.c
+++ b/net/netfilter/ipvs/ip_vs_app.c
@@ -589,13 +589,3 @@ void __net_exit ip_vs_app_net_cleanup(struct net *net)
{
proc_net_remove(net, "ip_vs_app");
}
-
-int __init ip_vs_app_init(void)
-{
- return 0;
-}
-
-
-void ip_vs_app_cleanup(void)
-{
-}
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 4582716..91802b1 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -1987,36 +1987,23 @@ static int __init ip_vs_init(void)
{
int ret;
- ip_vs_estimator_init();
ret = ip_vs_control_init();
if (ret < 0) {
pr_err("can't setup control.\n");
- goto cleanup_estimator;
+ goto cleanup_out;
}
ip_vs_protocol_init();
- ret = ip_vs_app_init();
- if (ret < 0) {
- pr_err("can't setup application helper.\n");
- goto cleanup_protocol;
- }
-
ret = ip_vs_conn_init();
if (ret < 0) {
pr_err("can't setup connection table.\n");
- goto cleanup_app;
- }
-
- ret = ip_vs_sync_init();
- if (ret < 0) {
- pr_err("can't setup sync data.\n");
- goto cleanup_conn;
+ goto cleanup_protocol;
}
ret = register_pernet_subsys(&ipvs_core_ops); /* Alloc ip_vs struct */
if (ret < 0)
- goto cleanup_sync;
+ goto cleanup_conn;
ret = register_pernet_device(&ipvs_core_dev_ops);
if (ret < 0)
@@ -2036,17 +2023,12 @@ cleanup_dev:
unregister_pernet_device(&ipvs_core_dev_ops);
cleanup_sub:
unregister_pernet_subsys(&ipvs_core_ops);
-cleanup_sync:
- ip_vs_sync_cleanup();
cleanup_conn:
ip_vs_conn_cleanup();
-cleanup_app:
- ip_vs_app_cleanup();
cleanup_protocol:
ip_vs_protocol_cleanup();
ip_vs_control_cleanup();
-cleanup_estimator:
- ip_vs_estimator_cleanup();
+cleanup_out:
return ret;
}
@@ -2055,12 +2037,9 @@ static void __exit ip_vs_cleanup(void)
nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
unregister_pernet_device(&ipvs_core_dev_ops);
unregister_pernet_subsys(&ipvs_core_ops); /* free ip_vs struct */
- ip_vs_sync_cleanup();
ip_vs_conn_cleanup();
- ip_vs_app_cleanup();
ip_vs_protocol_cleanup();
ip_vs_control_cleanup();
- ip_vs_estimator_cleanup();
pr_info("ipvs unloaded.\n");
}
diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c
index f5d2a01..0fac601 100644
--- a/net/netfilter/ipvs/ip_vs_est.c
+++ b/net/netfilter/ipvs/ip_vs_est.c
@@ -207,12 +207,3 @@ void __net_exit ip_vs_estimator_net_cleanup(struct net *net)
{
del_timer_sync(&net_ipvs(net)->est_timer);
}
-
-int __init ip_vs_estimator_init(void)
-{
- return 0;
-}
-
-void ip_vs_estimator_cleanup(void)
-{
-}
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index 58bfabb..7ee7215 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -1689,12 +1689,3 @@ void ip_vs_sync_net_cleanup(struct net *net)
if (retc && retc != -ESRCH)
pr_err("Failed to stop Backup Daemon\n");
}
-
-int __init ip_vs_sync_init(void)
-{
- return 0;
-}
-
-void ip_vs_sync_cleanup(void)
-{
-}
--
1.7.2.3
^ permalink raw reply related
* Re: [PATCH v4 2/5] can: add rtnetlink support
From: Oliver Hartkopp @ 2011-05-01 17:16 UTC (permalink / raw)
To: Kurt Van Dijck; +Cc: socketcan-core, netdev
In-Reply-To: <20110427085705.GC757@kurt.e-circ.dyndns.org>
On 27.04.2011 10:57, Kurt Van Dijck wrote:
> This patch adds rtnetlink support for AF_CAN. This support is really
> a multiplexer towards the different CAN protocols.
Hello Kurt,
i applied all your patches for the can-utils and the network layer stuff to
the BerliOS SVN in socketcan/branches/j1939 for testing.
Besides some minor adaptions to support the SVN i left out some infrastructure
changes you made in patch 2/5 to constify this ...
> -static struct can_proto *proto_tab[CAN_NPROTO] __read_mostly;
> +static const struct can_proto *proto_tab[CAN_NPROTO] __read_mostly;
and this ...
> -static struct can_proto *can_try_module_get(int protocol)
> +static const struct can_proto *can_try_module_get(int protocol)
(..)
> +static inline void can_put_proto(const struct can_proto *cp)
> +{
> + module_put(cp->prot->owner);
> +}
These infrastructure changes did not really belong to the rtnetlink support.
The can-j1939.ko builds properly in the SVN against 2.6.39-rc5 and the
net-next-2.6 tree - and e.g. against a debian wheezy kernel:
make KERNELDIR=/usr/src/linux-headers-2.6.38-2-686-bigmem
As it is pretty easy now to build the kernel modules & your provided can-utils
we hopefully get some more feedback from j1939 users.
Best regards,
Oliver
^ permalink raw reply
* Re: [Bugme-new] [Bug 34182] New: Hard hang arising from TCP/IP related bug in 2.6.39-rc4
From: Andrew Morton @ 2011-05-01 17:42 UTC (permalink / raw)
To: netdev; +Cc: bugzilla-daemon, bugme-daemon, htmldeveloper
In-Reply-To: <bug-34182-10286@https.bugzilla.kernel.org/>
(switched to email. Please respond via emailed reply-to-all, not via the
bugzilla web interface).
On Sun, 1 May 2011 17:32:07 GMT bugzilla-daemon@bugzilla.kernel.org wrote:
> https://bugzilla.kernel.org/show_bug.cgi?id=34182
>
> Summary: Hard hang arising from TCP/IP related bug in
> 2.6.39-rc4
> Product: Networking
> Version: 2.5
> Kernel Version: 2.6.39-rc4
> Platform: All
> OS/Version: Linux
> Tree: Mainline
> Status: NEW
> Severity: blocking
> Priority: P1
> Component: IPV4
> AssignedTo: shemminger@linux-foundation.org
> ReportedBy: htmldeveloper@gmail.com
> Regression: No
>
>
> Created an attachment (id=56082)
> --> (https://bugzilla.kernel.org/attachment.cgi?id=56082)
> kernel crash log via dmesg
>
> I did a git-update of linus git tree on 27 Apr 2011, built the new kernel
> image. Ever since using the new image, I have been *consistently* getting
> many crashes - especially whenever my google chrome is retoring all its
> previous session connection.
>
> Two crashes (entire system freezes) are shown in attachment. Ever since I
> have revert to previous version - as booting up twice and consistently twice it
> will fail within a few minutes after Chrome is used.
>
> v2.6.39-rc4-245-g4175242
>
> Previously working version: 2.6.38-rc2+. Did not test anything between
> 2.6.38-rc2+ and 2.6.39-rc3, and 2.6.39-rc3 failed for me in other ways as well.
>
> (http://bugzilla.kernel.org/show_bug.cgi?id=33272)
>
^ permalink raw reply
* Re: [v2 PATCH 0/6] IPVS: init and cleanup.
From: Julian Anastasov @ 2011-05-01 17:48 UTC (permalink / raw)
To: Hans Schillstrom
Cc: horms, ebiederm, lvs-devel, netdev, netfilter-devel,
hans.schillstrom
In-Reply-To: <1304268618-18103-1-git-send-email-hans@schillstrom.com>
Hello,
On Sun, 1 May 2011, Hans Schillstrom wrote:
> This patch series handles exit from a network name space.
>
> REVISION
>
> This is version 4
>
> OVERVIEW
> Basically there was three faults in the netns implementation.
> - Kernel threads hold devices and preventing an exit.
> - dst cache holds references to devices.
> - Services was not always released.
>
> Patch 1 & 3 contains the functionality
> 4 renames funcctions
> 5 removes empty functions
> 6 Debuging.
>
> IMPLEMENTATION
> - Avoid to increment the usage counter for kernel threads.
> this is done in the first patch.
> - Patch 3 tries to restore the cleanup order.
> Add NETDEV_UNREGISTER notification for dst_reset
> (eleased version could not handle unregistration of netdevices.)
>
> Comments from Eric, Julian and Simon implmented.
>
> Revision 3
> Residies in patch 3
> Throttle renamed to enable.
> Comments from Julian implemented
> Check enable in ip_vs_in, ip_vs_out and ip_vs_forward_icmp*
> Remove in ip_vs_in_icmp*.
> ip_vs_svc_reset() moved into ip_vs_dst_event().
> ip_vs_service_cleanup() uses ip_vs_flush and mutex lock.
> ip_vs_unlink_service_nolock() added.
>
> Revision 4
> ip_vs_unlink_service_nolock() removed.
> ip_vs_flush() reverted.
> Return code check changed in stop thread.
Not sure about patch 1 but patches 2-6 in v4 look
good to me. Thanks!
Acked-by: Julian Anastasov <ja@ssi.bg>
^ permalink raw reply
* [PATCH 1/4] batman-adv: orig_hash_find() manages rcu_lock/unlock internally
From: Sven Eckelmann @ 2011-05-01 21:10 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
In-Reply-To: <1304284234-27338-1-git-send-email-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
From: Antonio Quartulli <ordex-GaUfNO9RBHfsrOwW+9ziJQ@public.gmane.org>
orig_hash_find() manages rcu_lock/unlock internally and doesn't need to
be surrounded by rcu_read_lock() / rcu_read_unlock() anymore
Signed-off-by: Antonio Quartulli <ordex-GaUfNO9RBHfsrOwW+9ziJQ@public.gmane.org>
Acked-by: Marek Lindner <lindner_marek-LWAfsSFWpa4@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
net/batman-adv/routing.c | 16 ++--------------
1 files changed, 2 insertions(+), 14 deletions(-)
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index f6c6422..2d77bd3 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -1310,13 +1310,10 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
}
/* get routing information */
- rcu_read_lock();
orig_node = orig_hash_find(bat_priv, unicast_packet->dest);
if (!orig_node)
- goto unlock;
-
- rcu_read_unlock();
+ goto out;
/* find_router() increases neigh_nodes refcount if found. */
neigh_node = find_router(bat_priv, orig_node, recv_if);
@@ -1362,10 +1359,7 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
/* route it */
send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
ret = NET_RX_SUCCESS;
- goto out;
-unlock:
- rcu_read_unlock();
out:
if (neigh_node)
neigh_node_free_ref(neigh_node);
@@ -1464,13 +1458,10 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
if (bcast_packet->ttl < 2)
goto out;
- rcu_read_lock();
orig_node = orig_hash_find(bat_priv, bcast_packet->orig);
if (!orig_node)
- goto rcu_unlock;
-
- rcu_read_unlock();
+ goto out;
spin_lock_bh(&orig_node->bcast_seqno_lock);
@@ -1501,9 +1492,6 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
ret = NET_RX_SUCCESS;
goto out;
-rcu_unlock:
- rcu_read_unlock();
- goto out;
spin_unlock:
spin_unlock_bh(&orig_node->bcast_seqno_lock);
out:
--
1.7.4.4
^ permalink raw reply related
* [PATCH 2/4] batman-adv: Move definition of atomic_dec_not_zero() into main.h
From: Sven Eckelmann @ 2011-05-01 21:10 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
In-Reply-To: <1304284234-27338-1-git-send-email-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
From: Antonio Quartulli <ordex-GaUfNO9RBHfsrOwW+9ziJQ@public.gmane.org>
atomic_dec_not_zero() is very useful and it is currently defined
multiple times. So it is possible to move it in main.h
Signed-off-by: Antonio Quartulli <ordex-GaUfNO9RBHfsrOwW+9ziJQ@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
net/batman-adv/aggregation.c | 1 -
net/batman-adv/main.h | 2 ++
net/batman-adv/send.c | 1 -
3 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/batman-adv/aggregation.c b/net/batman-adv/aggregation.c
index af45d6b..c11788c 100644
--- a/net/batman-adv/aggregation.c
+++ b/net/batman-adv/aggregation.c
@@ -95,7 +95,6 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet,
return false;
}
-#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
/* create a new aggregated packet and add this packet to it */
static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
unsigned long send_time, bool direct_link,
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index dc24869..ace7285 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -175,4 +175,6 @@ static inline int compare_eth(void *data1, void *data2)
return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
}
+#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
+
#endif /* _NET_BATMAN_ADV_MAIN_H_ */
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index e78670c..7650e2b 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -393,7 +393,6 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv,
send_time);
}
-#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
/* add a broadcast packet to the queue and setup timers. broadcast packets
* are sent multiple times to increase probability for beeing received.
*
--
1.7.4.4
^ permalink raw reply related
* [PATCH 3/4] batman-adv: fix gw_node_update() and gw_election()
From: Sven Eckelmann @ 2011-05-01 21:10 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
In-Reply-To: <1304284234-27338-1-git-send-email-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
From: Antonio Quartulli <ordex-GaUfNO9RBHfsrOwW+9ziJQ@public.gmane.org>
This is a regression from c4aac1ab9b973798163b34939b522f01e4d28ac9
- gw_node_update() doesn't add a new gw_node in case of empty curr_gw.
This means that at the beginning no gw_node is added, leading to an
empty gateway list.
- gw_election() is terminating in case of curr_gw == NULL. It has to
terminate in case of curr_gw != NULL
Signed-off-by: Antonio Quartulli <ordex-GaUfNO9RBHfsrOwW+9ziJQ@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
net/batman-adv/gateway_client.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 2acd7a6..af128ef 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -127,7 +127,7 @@ void gw_election(struct bat_priv *bat_priv)
return;
curr_gw = gw_get_selected_gw_node(bat_priv);
- if (!curr_gw)
+ if (curr_gw)
goto out;
rcu_read_lock();
@@ -310,9 +310,13 @@ void gw_node_update(struct bat_priv *bat_priv,
struct hlist_node *node;
struct gw_node *gw_node, *curr_gw;
+ /**
+ * Note: We don't need a NULL check here, since curr_gw never gets
+ * dereferenced. If curr_gw is NULL we also should not exit as we may
+ * have this gateway in our list (duplication check!) even though we
+ * have no currently selected gateway.
+ */
curr_gw = gw_get_selected_gw_node(bat_priv);
- if (!curr_gw)
- goto out;
rcu_read_lock();
hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
@@ -350,7 +354,7 @@ deselect:
gw_deselect(bat_priv);
unlock:
rcu_read_unlock();
-out:
+
if (curr_gw)
gw_node_free_ref(curr_gw);
}
--
1.7.4.4
^ permalink raw reply related
* [PATCH 4/4] batman-adv: Make bat_priv->primary_if an rcu protected pointer
From: Sven Eckelmann @ 2011-05-01 21:10 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r, Marek Lindner
In-Reply-To: <1304284234-27338-1-git-send-email-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
From: Marek Lindner <lindner_marek-LWAfsSFWpa4@public.gmane.org>
The rcu protected macros rcu_dereference() and rcu_assign_pointer()
for the bat_priv->primary_if need to be used, as well as spin/rcu locking.
Otherwise we might end up using a primary_if pointer pointing to already
freed memory.
Signed-off-by: Marek Lindner <lindner_marek-LWAfsSFWpa4@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
net/batman-adv/gateway_client.c | 33 ++++++++------
net/batman-adv/hard-interface.c | 83 ++++++++++++++++++++++++-----------
net/batman-adv/hard-interface.h | 18 ++++++++
net/batman-adv/icmp_socket.c | 19 ++++++--
net/batman-adv/originator.c | 34 +++++++++------
net/batman-adv/routing.c | 18 +++++---
net/batman-adv/send.c | 17 ++++++--
net/batman-adv/soft-interface.c | 64 +++++++++++++++++++--------
net/batman-adv/translation-table.c | 57 ++++++++++++++++++------
net/batman-adv/types.h | 2 +-
net/batman-adv/unicast.c | 16 +++++--
net/batman-adv/vis.c | 37 +++++++++++-----
12 files changed, 280 insertions(+), 118 deletions(-)
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index af128ef..65f3953 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -439,30 +439,32 @@ int gw_client_seq_print_text(struct seq_file *seq, void *offset)
{
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
+ struct hard_iface *primary_if;
struct gw_node *gw_node;
struct hlist_node *node;
- int gw_count = 0;
+ int gw_count = 0, ret = 0;
- if (!bat_priv->primary_if) {
-
- return seq_printf(seq, "BATMAN mesh %s disabled - please "
- "specify interfaces to enable it\n",
- net_dev->name);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - please "
+ "specify interfaces to enable it\n",
+ net_dev->name);
+ goto out;
}
- if (bat_priv->primary_if->if_status != IF_ACTIVE) {
-
- return seq_printf(seq, "BATMAN mesh %s disabled - "
- "primary interface not active\n",
- net_dev->name);
+ if (primary_if->if_status != IF_ACTIVE) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "primary interface not active\n",
+ net_dev->name);
+ goto out;
}
seq_printf(seq, " %-12s (%s/%i) %17s [%10s]: gw_class ... "
"[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n",
"Gateway", "#", TQ_MAX_VALUE, "Nexthop",
"outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR,
- bat_priv->primary_if->net_dev->name,
- bat_priv->primary_if->net_dev->dev_addr, net_dev->name);
+ primary_if->net_dev->name,
+ primary_if->net_dev->dev_addr, net_dev->name);
rcu_read_lock();
hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
@@ -480,7 +482,10 @@ int gw_client_seq_print_text(struct seq_file *seq, void *offset)
if (gw_count == 0)
seq_printf(seq, "No gateways in range ...\n");
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index b3058e4..3e888f1 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -110,47 +110,60 @@ out:
return hard_iface;
}
-static void update_primary_addr(struct bat_priv *bat_priv)
+static void primary_if_update_addr(struct bat_priv *bat_priv)
{
struct vis_packet *vis_packet;
+ struct hard_iface *primary_if;
+
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
vis_packet = (struct vis_packet *)
bat_priv->my_vis_info->skb_packet->data;
- memcpy(vis_packet->vis_orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
memcpy(vis_packet->sender_orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ primary_if->net_dev->dev_addr, ETH_ALEN);
+
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
}
-static void set_primary_if(struct bat_priv *bat_priv,
- struct hard_iface *hard_iface)
+static void primary_if_select(struct bat_priv *bat_priv,
+ struct hard_iface *new_hard_iface)
{
+ struct hard_iface *curr_hard_iface;
struct batman_packet *batman_packet;
- struct hard_iface *old_if;
- if (hard_iface && !atomic_inc_not_zero(&hard_iface->refcount))
- hard_iface = NULL;
+ spin_lock_bh(&hardif_list_lock);
- old_if = bat_priv->primary_if;
- bat_priv->primary_if = hard_iface;
+ if (new_hard_iface && !atomic_inc_not_zero(&new_hard_iface->refcount))
+ new_hard_iface = NULL;
- if (old_if)
- hardif_free_ref(old_if);
+ curr_hard_iface = bat_priv->primary_if;
+ rcu_assign_pointer(bat_priv->primary_if, new_hard_iface);
- if (!bat_priv->primary_if)
- return;
+ if (curr_hard_iface)
+ hardif_free_ref(curr_hard_iface);
- batman_packet = (struct batman_packet *)(hard_iface->packet_buff);
+ if (!new_hard_iface)
+ goto out;
+
+ batman_packet = (struct batman_packet *)(new_hard_iface->packet_buff);
batman_packet->flags = PRIMARIES_FIRST_HOP;
batman_packet->ttl = TTL;
- update_primary_addr(bat_priv);
+ primary_if_update_addr(bat_priv);
/***
* hacky trick to make sure that we send the HNA information via
* our new primary interface
*/
atomic_set(&bat_priv->hna_local_changed, 1);
+
+out:
+ spin_unlock_bh(&hardif_list_lock);
}
static bool hardif_is_iface_up(struct hard_iface *hard_iface)
@@ -236,9 +249,10 @@ void update_min_mtu(struct net_device *soft_iface)
static void hardif_activate_interface(struct hard_iface *hard_iface)
{
struct bat_priv *bat_priv;
+ struct hard_iface *primary_if = NULL;
if (hard_iface->if_status != IF_INACTIVE)
- return;
+ goto out;
bat_priv = netdev_priv(hard_iface->soft_iface);
@@ -249,14 +263,18 @@ static void hardif_activate_interface(struct hard_iface *hard_iface)
* the first active interface becomes our primary interface or
* the next active interface after the old primay interface was removed
*/
- if (!bat_priv->primary_if)
- set_primary_if(bat_priv, hard_iface);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ primary_if_select(bat_priv, hard_iface);
bat_info(hard_iface->soft_iface, "Interface activated: %s\n",
hard_iface->net_dev->name);
update_min_mtu(hard_iface->soft_iface);
- return;
+
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
}
static void hardif_deactivate_interface(struct hard_iface *hard_iface)
@@ -386,12 +404,13 @@ err:
void hardif_disable_interface(struct hard_iface *hard_iface)
{
struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+ struct hard_iface *primary_if = NULL;
if (hard_iface->if_status == IF_ACTIVE)
hardif_deactivate_interface(hard_iface);
if (hard_iface->if_status != IF_INACTIVE)
- return;
+ goto out;
bat_info(hard_iface->soft_iface, "Removing interface: %s\n",
hard_iface->net_dev->name);
@@ -400,11 +419,12 @@ void hardif_disable_interface(struct hard_iface *hard_iface)
bat_priv->num_ifaces--;
orig_hash_del_if(hard_iface, bat_priv->num_ifaces);
- if (hard_iface == bat_priv->primary_if) {
+ primary_if = primary_if_get_selected(bat_priv);
+ if (hard_iface == primary_if) {
struct hard_iface *new_if;
new_if = hardif_get_active(hard_iface->soft_iface);
- set_primary_if(bat_priv, new_if);
+ primary_if_select(bat_priv, new_if);
if (new_if)
hardif_free_ref(new_if);
@@ -425,6 +445,10 @@ void hardif_disable_interface(struct hard_iface *hard_iface)
hard_iface->soft_iface = NULL;
hardif_free_ref(hard_iface);
+
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
}
static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
@@ -514,6 +538,7 @@ static int hard_if_event(struct notifier_block *this,
{
struct net_device *net_dev = (struct net_device *)ptr;
struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev);
+ struct hard_iface *primary_if = NULL;
struct bat_priv *bat_priv;
if (!hard_iface && event == NETDEV_REGISTER)
@@ -549,8 +574,12 @@ static int hard_if_event(struct notifier_block *this,
update_mac_addresses(hard_iface);
bat_priv = netdev_priv(hard_iface->soft_iface);
- if (hard_iface == bat_priv->primary_if)
- update_primary_addr(bat_priv);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto hardif_put;
+
+ if (hard_iface == primary_if)
+ primary_if_update_addr(bat_priv);
break;
default:
break;
@@ -559,6 +588,8 @@ static int hard_if_event(struct notifier_block *this,
hardif_put:
hardif_free_ref(hard_iface);
out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
return NOTIFY_DONE;
}
diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h
index a9ddf36..6426599 100644
--- a/net/batman-adv/hard-interface.h
+++ b/net/batman-adv/hard-interface.h
@@ -45,4 +45,22 @@ static inline void hardif_free_ref(struct hard_iface *hard_iface)
call_rcu(&hard_iface->rcu, hardif_free_rcu);
}
+static inline struct hard_iface *primary_if_get_selected(
+ struct bat_priv *bat_priv)
+{
+ struct hard_iface *hard_iface;
+
+ rcu_read_lock();
+ hard_iface = rcu_dereference(bat_priv->primary_if);
+ if (!hard_iface)
+ goto out;
+
+ if (!atomic_inc_not_zero(&hard_iface->refcount))
+ hard_iface = NULL;
+
+out:
+ rcu_read_unlock();
+ return hard_iface;
+}
+
#endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index 49079c2..fa22ba2 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -153,6 +153,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
{
struct socket_client *socket_client = file->private_data;
struct bat_priv *bat_priv = socket_client->bat_priv;
+ struct hard_iface *primary_if = NULL;
struct sk_buff *skb;
struct icmp_packet_rr *icmp_packet;
@@ -167,15 +168,21 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
return -EINVAL;
}
- if (!bat_priv->primary_if)
- return -EFAULT;
+ primary_if = primary_if_get_selected(bat_priv);
+
+ if (!primary_if) {
+ len = -EFAULT;
+ goto out;
+ }
if (len >= sizeof(struct icmp_packet_rr))
packet_len = sizeof(struct icmp_packet_rr);
skb = dev_alloc_skb(packet_len + sizeof(struct ethhdr));
- if (!skb)
- return -ENOMEM;
+ if (!skb) {
+ len = -ENOMEM;
+ goto out;
+ }
skb_reserve(skb, sizeof(struct ethhdr));
icmp_packet = (struct icmp_packet_rr *)skb_put(skb, packet_len);
@@ -233,7 +240,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
goto dst_unreach;
memcpy(icmp_packet->orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ primary_if->net_dev->dev_addr, ETH_ALEN);
if (packet_len == sizeof(struct icmp_packet_rr))
memcpy(icmp_packet->rr,
@@ -248,6 +255,8 @@ dst_unreach:
free_skb:
kfree_skb(skb);
out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
if (neigh_node)
neigh_node_free_ref(neigh_node);
if (orig_node)
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 5b8fe32..ef4a9be 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -405,29 +405,34 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
struct hashtable_t *hash = bat_priv->orig_hash;
struct hlist_node *node, *node_tmp;
struct hlist_head *head;
+ struct hard_iface *primary_if;
struct orig_node *orig_node;
struct neigh_node *neigh_node, *neigh_node_tmp;
int batman_count = 0;
int last_seen_secs;
int last_seen_msecs;
- int i;
+ int i, ret = 0;
- if ((!bat_priv->primary_if) ||
- (bat_priv->primary_if->if_status != IF_ACTIVE)) {
- if (!bat_priv->primary_if)
- return seq_printf(seq, "BATMAN mesh %s disabled - "
- "please specify interfaces to enable it\n",
- net_dev->name);
+ primary_if = primary_if_get_selected(bat_priv);
- return seq_printf(seq, "BATMAN mesh %s "
- "disabled - primary interface not active\n",
- net_dev->name);
+ if (!primary_if) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
+ goto out;
+ }
+
+ if (primary_if->if_status != IF_ACTIVE) {
+ ret = seq_printf(seq, "BATMAN mesh %s "
+ "disabled - primary interface not active\n",
+ net_dev->name);
+ goto out;
}
seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n",
SOURCE_VERSION, REVISION_VERSION_STR,
- bat_priv->primary_if->net_dev->name,
- bat_priv->primary_if->net_dev->dev_addr, net_dev->name);
+ primary_if->net_dev->name,
+ primary_if->net_dev->dev_addr, net_dev->name);
seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
"Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop",
"outgoingIF", "Potential nexthops");
@@ -474,7 +479,10 @@ next:
if (batman_count == 0)
seq_printf(seq, "No batman nodes in range ...\n");
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 2d77bd3..49f5715 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -904,6 +904,7 @@ int recv_bat_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
static int recv_my_icmp_packet(struct bat_priv *bat_priv,
struct sk_buff *skb, size_t icmp_len)
{
+ struct hard_iface *primary_if = NULL;
struct orig_node *orig_node = NULL;
struct neigh_node *router = NULL;
struct icmp_packet_rr *icmp_packet;
@@ -917,7 +918,8 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
goto out;
}
- if (!bat_priv->primary_if)
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
goto out;
/* answer echo request (ping) */
@@ -937,8 +939,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
icmp_packet = (struct icmp_packet_rr *)skb->data;
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
- memcpy(icmp_packet->orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
icmp_packet->msg_type = ECHO_REPLY;
icmp_packet->ttl = TTL;
@@ -946,6 +947,8 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
ret = NET_RX_SUCCESS;
out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
if (router)
neigh_node_free_ref(router);
if (orig_node)
@@ -956,6 +959,7 @@ out:
static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
struct sk_buff *skb)
{
+ struct hard_iface *primary_if = NULL;
struct orig_node *orig_node = NULL;
struct neigh_node *router = NULL;
struct icmp_packet *icmp_packet;
@@ -971,7 +975,8 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
goto out;
}
- if (!bat_priv->primary_if)
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
goto out;
/* get routing information */
@@ -990,8 +995,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
icmp_packet = (struct icmp_packet *)skb->data;
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
- memcpy(icmp_packet->orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
icmp_packet->msg_type = TTL_EXCEEDED;
icmp_packet->ttl = TTL;
@@ -999,6 +1003,8 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
ret = NET_RX_SUCCESS;
out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
if (router)
neigh_node_free_ref(router);
if (orig_node)
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 7650e2b..02b541a 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -244,6 +244,7 @@ static void rebuild_batman_packet(struct bat_priv *bat_priv,
void schedule_own_packet(struct hard_iface *hard_iface)
{
struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+ struct hard_iface *primary_if;
unsigned long send_time;
struct batman_packet *batman_packet;
int vis_server;
@@ -253,6 +254,7 @@ void schedule_own_packet(struct hard_iface *hard_iface)
return;
vis_server = atomic_read(&bat_priv->vis_mode);
+ primary_if = primary_if_get_selected(bat_priv);
/**
* the interface gets activated here to avoid race conditions between
@@ -266,7 +268,7 @@ void schedule_own_packet(struct hard_iface *hard_iface)
/* if local hna has changed and interface is a primary interface */
if ((atomic_read(&bat_priv->hna_local_changed)) &&
- (hard_iface == bat_priv->primary_if))
+ (hard_iface == primary_if))
rebuild_batman_packet(bat_priv, hard_iface);
/**
@@ -284,7 +286,7 @@ void schedule_own_packet(struct hard_iface *hard_iface)
else
batman_packet->flags &= ~VIS_SERVER;
- if ((hard_iface == bat_priv->primary_if) &&
+ if ((hard_iface == primary_if) &&
(atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER))
batman_packet->gw_flags =
(uint8_t)atomic_read(&bat_priv->gw_bandwidth);
@@ -299,6 +301,9 @@ void schedule_own_packet(struct hard_iface *hard_iface)
hard_iface->packet_buff,
hard_iface->packet_len,
hard_iface, 1, send_time);
+
+ if (primary_if)
+ hardif_free_ref(primary_if);
}
void schedule_forward_packet(struct orig_node *orig_node,
@@ -403,6 +408,7 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv,
* skb is freed. */
int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
{
+ struct hard_iface *primary_if = NULL;
struct forw_packet *forw_packet;
struct bcast_packet *bcast_packet;
@@ -411,7 +417,8 @@ int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
goto out;
}
- if (!bat_priv->primary_if)
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
goto out;
forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
@@ -430,7 +437,7 @@ int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
skb_reset_mac_header(skb);
forw_packet->skb = skb;
- forw_packet->if_incoming = bat_priv->primary_if;
+ forw_packet->if_incoming = primary_if;
/* how often did we send the bcast packet ? */
forw_packet->num_packets = 0;
@@ -443,6 +450,8 @@ packet_free:
out_and_inc:
atomic_inc(&bat_priv->bcast_queue_left);
out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
return NETDEV_TX_BUSY;
}
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 58ce440..ea5e58c 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -215,13 +215,24 @@ int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
struct softif_neigh *softif_neigh;
+ struct hard_iface *primary_if;
struct hlist_node *node;
struct softif_neigh *curr_softif_neigh;
+ int ret = 0;
- if (!bat_priv->primary_if) {
- return seq_printf(seq, "BATMAN mesh %s disabled - "
- "please specify interfaces to enable it\n",
- net_dev->name);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
+ goto out;
+ }
+
+ if (primary_if->if_status != IF_ACTIVE) {
+ ret = seq_printf(seq, "BATMAN mesh %s "
+ "disabled - primary interface not active\n",
+ net_dev->name);
+ goto out;
}
seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name);
@@ -238,7 +249,10 @@ int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
if (curr_softif_neigh)
softif_neigh_free_ref(curr_softif_neigh);
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
@@ -247,7 +261,8 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
struct bat_priv *bat_priv = netdev_priv(dev);
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
struct batman_packet *batman_packet;
- struct softif_neigh *softif_neigh;
+ struct softif_neigh *softif_neigh = NULL;
+ struct hard_iface *primary_if = NULL;
struct softif_neigh *curr_softif_neigh = NULL;
if (ntohs(ethhdr->h_proto) == ETH_P_8021Q)
@@ -257,28 +272,34 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN);
if (batman_packet->version != COMPAT_VERSION)
- goto err;
+ goto out;
if (batman_packet->packet_type != BAT_PACKET)
- goto err;
+ goto out;
if (!(batman_packet->flags & PRIMARIES_FIRST_HOP))
- goto err;
+ goto out;
if (is_my_mac(batman_packet->orig))
- goto err;
+ goto out;
softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid);
-
if (!softif_neigh)
- goto err;
+ goto out;
curr_softif_neigh = softif_neigh_get_selected(bat_priv);
+ if (!curr_softif_neigh)
+ goto out;
+
if (curr_softif_neigh == softif_neigh)
goto out;
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
+
/* we got a neighbor but its mac is 'bigger' than ours */
- if (memcmp(bat_priv->primary_if->net_dev->dev_addr,
+ if (memcmp(primary_if->net_dev->dev_addr,
softif_neigh->addr, ETH_ALEN) < 0)
goto out;
@@ -300,7 +321,7 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
/* close own batX device and use softif_neigh as exit node */
if ((!curr_softif_neigh) &&
(memcmp(softif_neigh->addr,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) {
+ primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) {
bat_dbg(DBG_ROUTES, bat_priv,
"Setting mesh exit point to %pM (vid: %d).\n",
softif_neigh->addr, softif_neigh->vid);
@@ -310,12 +331,13 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
}
out:
- softif_neigh_free_ref(softif_neigh);
-err:
kfree_skb(skb);
+ if (softif_neigh)
+ softif_neigh_free_ref(softif_neigh);
if (curr_softif_neigh)
softif_neigh_free_ref(curr_softif_neigh);
-
+ if (primary_if)
+ hardif_free_ref(primary_if);
return;
}
@@ -371,6 +393,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
{
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
struct bat_priv *bat_priv = netdev_priv(soft_iface);
+ struct hard_iface *primary_if = NULL;
struct bcast_packet *bcast_packet;
struct vlan_ethhdr *vhdr;
struct softif_neigh *curr_softif_neigh = NULL;
@@ -420,7 +443,8 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
/* ethernet packet should be broadcasted */
if (do_bcast) {
- if (!bat_priv->primary_if)
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
goto dropped;
if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0)
@@ -436,7 +460,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
/* hw address of first interface is the orig mac because only
* this mac is known throughout the mesh */
memcpy(bcast_packet->orig,
- bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ primary_if->net_dev->dev_addr, ETH_ALEN);
/* set broadcast sequence number */
bcast_packet->seqno =
@@ -466,6 +490,8 @@ dropped_freed:
end:
if (curr_softif_neigh)
softif_neigh_free_ref(curr_softif_neigh);
+ if (primary_if)
+ hardif_free_ref(primary_if);
return NETDEV_TX_OK;
}
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 8d15b48..f931830 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -22,6 +22,7 @@
#include "main.h"
#include "translation-table.h"
#include "soft-interface.h"
+#include "hard-interface.h"
#include "hash.h"
#include "originator.h"
@@ -237,16 +238,26 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset)
struct bat_priv *bat_priv = netdev_priv(net_dev);
struct hashtable_t *hash = bat_priv->hna_local_hash;
struct hna_local_entry *hna_local_entry;
+ struct hard_iface *primary_if;
struct hlist_node *node;
struct hlist_head *head;
size_t buf_size, pos;
char *buff;
- int i;
+ int i, ret = 0;
- if (!bat_priv->primary_if) {
- return seq_printf(seq, "BATMAN mesh %s disabled - "
- "please specify interfaces to enable it\n",
- net_dev->name);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
+ goto out;
+ }
+
+ if (primary_if->if_status != IF_ACTIVE) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "primary interface not active\n",
+ net_dev->name);
+ goto out;
}
seq_printf(seq, "Locally retrieved addresses (from %s) "
@@ -269,7 +280,8 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset)
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
spin_unlock_bh(&bat_priv->hna_lhash_lock);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out;
}
buff[0] = '\0';
@@ -291,7 +303,10 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset)
seq_printf(seq, "%s", buff);
kfree(buff);
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
static void _hna_local_del(struct hlist_node *node, void *arg)
@@ -468,16 +483,26 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset)
struct bat_priv *bat_priv = netdev_priv(net_dev);
struct hashtable_t *hash = bat_priv->hna_global_hash;
struct hna_global_entry *hna_global_entry;
+ struct hard_iface *primary_if;
struct hlist_node *node;
struct hlist_head *head;
size_t buf_size, pos;
char *buff;
- int i;
+ int i, ret = 0;
- if (!bat_priv->primary_if) {
- return seq_printf(seq, "BATMAN mesh %s disabled - "
- "please specify interfaces to enable it\n",
- net_dev->name);
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - please "
+ "specify interfaces to enable it\n",
+ net_dev->name);
+ goto out;
+ }
+
+ if (primary_if->if_status != IF_ACTIVE) {
+ ret = seq_printf(seq, "BATMAN mesh %s disabled - "
+ "primary interface not active\n",
+ net_dev->name);
+ goto out;
}
seq_printf(seq, "Globally announced HNAs received via the mesh %s\n",
@@ -499,7 +524,8 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset)
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
spin_unlock_bh(&bat_priv->hna_ghash_lock);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out;
}
buff[0] = '\0';
pos = 0;
@@ -522,7 +548,10 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset)
seq_printf(seq, "%s", buff);
kfree(buff);
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
static void _hna_global_del_orig(struct bat_priv *bat_priv,
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 75123b1..947bafc 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -149,7 +149,6 @@ struct bat_priv {
struct hlist_head softif_neigh_list;
struct softif_neigh __rcu *softif_neigh;
struct debug_log *debug_log;
- struct hard_iface *primary_if;
struct kobject *mesh_obj;
struct dentry *debug_dir;
struct hlist_head forw_bat_list;
@@ -174,6 +173,7 @@ struct bat_priv {
struct delayed_work orig_work;
struct delayed_work vis_work;
struct gw_node __rcu *curr_gw; /* rcu protected pointer */
+ struct hard_iface __rcu *primary_if; /* rcu protected pointer */
struct vis_info *my_vis_info;
};
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
index d46acc8..b46cbf1 100644
--- a/net/batman-adv/unicast.c
+++ b/net/batman-adv/unicast.c
@@ -221,15 +221,17 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
struct hard_iface *hard_iface, uint8_t dstaddr[])
{
struct unicast_packet tmp_uc, *unicast_packet;
+ struct hard_iface *primary_if;
struct sk_buff *frag_skb;
struct unicast_frag_packet *frag1, *frag2;
int uc_hdr_len = sizeof(struct unicast_packet);
int ucf_hdr_len = sizeof(struct unicast_frag_packet);
int data_len = skb->len - uc_hdr_len;
- int large_tail = 0;
+ int large_tail = 0, ret = NET_RX_DROP;
uint16_t seqno;
- if (!bat_priv->primary_if)
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
goto dropped;
frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len);
@@ -254,7 +256,7 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
frag1->version = COMPAT_VERSION;
frag1->packet_type = BAT_UNICAST_FRAG;
- memcpy(frag1->orig, bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(frag1->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
memcpy(frag2, frag1, sizeof(struct unicast_frag_packet));
if (data_len & 1)
@@ -269,13 +271,17 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
send_skb_packet(skb, hard_iface, dstaddr);
send_skb_packet(frag_skb, hard_iface, dstaddr);
- return NET_RX_SUCCESS;
+ ret = NET_RX_SUCCESS;
+ goto out;
drop_frag:
kfree_skb(frag_skb);
dropped:
kfree_skb(skb);
- return NET_RX_DROP;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index d4cc4f5..c8f571d 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -204,6 +204,7 @@ static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
int vis_seq_print_text(struct seq_file *seq, void *offset)
{
+ struct hard_iface *primary_if;
struct hlist_node *node;
struct hlist_head *head;
struct vis_info *info;
@@ -215,15 +216,18 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
HLIST_HEAD(vis_if_list);
struct if_list_entry *entry;
struct hlist_node *pos, *n;
- int i, j;
+ int i, j, ret = 0;
int vis_server = atomic_read(&bat_priv->vis_mode);
size_t buff_pos, buf_size;
char *buff;
int compare;
- if ((!bat_priv->primary_if) ||
- (vis_server == VIS_TYPE_CLIENT_UPDATE))
- return 0;
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
+
+ if (vis_server == VIS_TYPE_CLIENT_UPDATE)
+ goto out;
buf_size = 1;
/* Estimate length */
@@ -270,7 +274,8 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
spin_unlock_bh(&bat_priv->vis_hash_lock);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out;
}
buff[0] = '\0';
buff_pos = 0;
@@ -328,7 +333,10 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
seq_printf(seq, "%s", buff);
kfree(buff);
- return 0;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return ret;
}
/* add the info packet to the send list, if it was not
@@ -815,16 +823,20 @@ out:
/* only send one vis packet. called from send_vis_packets() */
static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
{
+ struct hard_iface *primary_if;
struct vis_packet *packet;
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
+
packet = (struct vis_packet *)info->skb_packet->data;
if (packet->ttl < 2) {
pr_debug("Error - can't send vis packet: ttl exceeded\n");
- return;
+ goto out;
}
- memcpy(packet->sender_orig, bat_priv->primary_if->net_dev->dev_addr,
- ETH_ALEN);
+ memcpy(packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
packet->ttl--;
if (is_broadcast_ether_addr(packet->target_orig))
@@ -832,6 +844,10 @@ static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
else
unicast_vis_packet(bat_priv, info);
packet->ttl++; /* restore TTL */
+
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
}
/* called from timer; send (and maybe generate) vis packet. */
@@ -858,8 +874,7 @@ static void send_vis_packets(struct work_struct *work)
kref_get(&info->refcount);
spin_unlock_bh(&bat_priv->vis_hash_lock);
- if (bat_priv->primary_if)
- send_vis_packet(bat_priv, info);
+ send_vis_packet(bat_priv, info);
spin_lock_bh(&bat_priv->vis_hash_lock);
send_list_del(info);
--
1.7.4.4
^ permalink raw reply related
* pull request: batman-adv 2011-05-01
From: Sven Eckelmann @ 2011-05-01 21:10 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n
Hi,
I would like to propose following patches for net-next-2.6/2.6.40. Marek
Lindner continued to convert different datastructures to use RCU. Antonio
Quartulli fixed an important bug introduced in the last patchset related to the
update of the current gateway. He also did some minor cleanup work.
I've removed the patch "net: batman-adv: remove rx_csum ethtool_ops" again
because you already applied it in your branch.
thanks,
Sven
The following changes since commit af20b710479ae662829cf739b521390daa7fcbcb:
batman-adv: Set the txqueuelen to zero when creating soft interface (2011-04-17 21:11:02 +0200)
are available in the git repository at:
git://git.open-mesh.org/ecsv/linux-merge.git batman-adv/next
Antonio Quartulli (3):
batman-adv: orig_hash_find() manages rcu_lock/unlock internally
batman-adv: Move definition of atomic_dec_not_zero() into main.h
batman-adv: fix gw_node_update() and gw_election()
Marek Lindner (1):
batman-adv: Make bat_priv->primary_if an rcu protected pointer
net/batman-adv/aggregation.c | 1 -
net/batman-adv/gateway_client.c | 45 ++++++++++++--------
net/batman-adv/hard-interface.c | 83 ++++++++++++++++++++++++-----------
net/batman-adv/hard-interface.h | 18 ++++++++
net/batman-adv/icmp_socket.c | 19 ++++++--
net/batman-adv/main.h | 2 +
net/batman-adv/originator.c | 34 +++++++++------
net/batman-adv/routing.c | 34 ++++++---------
net/batman-adv/send.c | 18 ++++++--
net/batman-adv/soft-interface.c | 64 +++++++++++++++++++--------
net/batman-adv/translation-table.c | 57 ++++++++++++++++++------
net/batman-adv/types.h | 2 +-
net/batman-adv/unicast.c | 16 +++++--
net/batman-adv/vis.c | 37 +++++++++++-----
14 files changed, 292 insertions(+), 138 deletions(-)
^ permalink raw reply
* Frequent spurious tx_timeouts for libertas
From: Daniel Drake @ 2011-05-01 21:21 UTC (permalink / raw)
To: netdev, libertas-dev
Hi,
The libertas driver works as follows:
Once successfully connected to wifi, it enables the TX queue.
When the network layer calls hard_start_xmit, the driver stores the
packet in memory, stops the TX queue with netif_stop_queue(), and
returns NETDEV_TX_OK.
Some time later, the libertas kernel thread wakes up, sees the new
packet stored for delivery, sends it to the card, then runs
netif_wake_queue() to get things moving again.
Sometimes the TX queue is stopped and started from other places (e.g.
while scanning for networks, which NetworkManager triggers every
couple of minutes)
Thus the TX queue is stopped and started very often.
The libertas tx_timeout handler is being called quite a lot, and quite
soon after boot we get this in the kernel logs (the first time it
happens):
[ 97.050101] ------------[ cut here ]------------
[ 97.054866] WARNING: at net/sched/sch_generic.c:258 dev_watchdog+0x102/0x17c
[ 97.062277] Hardware name: XO
[ 97.065335] NETDEV WATCHDOG: eth0 (libertas_sdio): transmit queue 0 timed out
<snip large trace>
This message seems bogus - all the recent transmissions happened correctly.
What is this watchdog trying to detect exactly? Using what criteria?
I had a look at the code and it doesn't quite make sense to me - also
explaining why we get this bogus message. Here's what happens:
1. Kernel asks libertas to transmit a packet; libertas stops the TX
queue and puts the packet in memory
2. Very shortly after, libertas thread picks up the packet, transmits
it via the card, and restarts the tx queue. The packet is transmitted
correctly, and the queue is awake again.
3. Shortly after (with no further TX activity occuring in this time),
NetworkManager starts scanning for networks. This causes the TX queue
to be stopped and started a few times over the space of a few seconds,
and during this time the queue is stopped for quite a while.
4. The netdev watchdog wakes up in one of these times when the TX
queue is stopped, and uses its criteria (last TX was a few seconds
ago, queue is currently stopped) to determine that a transmit timeout
has occurred (???)
Is libertas doing something wrong, or is this a bug/oddity in the network layer?
Also, while looking at this code, I spotted a bug in dev_watchdog():
/*
* old device drivers set dev->trans_start
*/
trans_start = txq->trans_start ? : dev->trans_start;
i.e. it is trying to figure out whether to read trans_start from txq
or dev. In both cases, trans_start is updated based on the value of
jiffies, which will occasionally be 0 (as it wraps around). Therefore
this line of code will occasionally make the wrong decision.
Daniel
^ permalink raw reply
* Re: [v2 PATCH 0/6] IPVS: init and cleanup.
From: Simon Horman @ 2011-05-01 23:15 UTC (permalink / raw)
To: Hans Schillström
Cc: Hans Schillstrom, ja@ssi.bg, ebiederm@xmission.com,
lvs-devel@vger.kernel.org, netdev@vger.kernel.org,
netfilter-devel@vger.kernel.org
In-Reply-To: <C8A6796DE7C66C4ABCBC18106CB6C1CC08232F0887@ESESSCMS0356.eemea.ericsson.se>
On Fri, Apr 29, 2011 at 11:48:39AM +0200, Hans Schillström wrote:
>
> >Subject: Re: [v2 PATCH 0/6] IPVS: init and cleanup.
> >
> >On Fri, Apr 29, 2011 at 08:25:28AM +0200, Hans Schillstrom wrote:
> > This patch series handles exit from a network name space.
> >
> >Hi Hans,
> >
> >thanks for your work on this.
> >I've looked over the patches and nothing catches my eye -
> >thanks for fixing up the things that I commented on previously.
> >
> >I think that patches 1 and 2 should be targeted at 2.6.39,
> >while the remainder look like 2.6.40 material. Does that
> >sound reasonable to you?
>
> I do prefer to keep them together,
> but if you want it in that way it's OK for me.
I understand that you'd like to keep things together,
but I think its too much change for .39 this late
in the rc series.
> We are doing a lot of tests right now with this patch set.
> If we found any issues I'll let you know.
Thanks
^ permalink raw reply
* Re: Frequent spurious tx_timeouts for libertas
From: Ben Hutchings @ 2011-05-02 2:24 UTC (permalink / raw)
To: Daniel Drake
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
libertas-dev-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, linux-wireless
In-Reply-To: <BANLkTintnaEj0DDjwQJjc4wpuz-c_QOGyg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Sun, 2011-05-01 at 22:21 +0100, Daniel Drake wrote:
[...]
> Sometimes the TX queue is stopped and started from other places (e.g.
> while scanning for networks, which NetworkManager triggers every
> couple of minutes)
>
> Thus the TX queue is stopped and started very often.
>
> The libertas tx_timeout handler is being called quite a lot, and quite
> soon after boot we get this in the kernel logs (the first time it
> happens):
>
> [ 97.050101] ------------[ cut here ]------------
> [ 97.054866] WARNING: at net/sched/sch_generic.c:258 dev_watchdog+0x102/0x17c
> [ 97.062277] Hardware name: XO
> [ 97.065335] NETDEV WATCHDOG: eth0 (libertas_sdio): transmit queue 0 timed out
> <snip large trace>
>
> This message seems bogus - all the recent transmissions happened correctly.
>
> What is this watchdog trying to detect exactly? Using what criteria?
I'll repeat my answer from the last time this was asked on netdev:
The watchdog fires when the software queue has been stopped *and* the
link has been reported as up for over dev->watchdog_timeo ticks.
The software queue should be stopped iff the hardware queue is full or
nearly full. If the software queue remains stopped and the link is
still reported up, then one of these things is happening:
1. The link went down but the driver didn't notice
2. TX completions are not being indicated or handled correctly
3. The hardware TX path has locked up
4. The link is stalled by excessive pause frames or collisions
5. Timeout is too low and/or low watermark is too high
(there may be other explanations)
I think the watchdog is primarily meant to deal with case 3, though all
of cases 1-3 may be worked around by resetting the hardware.
And now, for the specific case of libertas:
It appears that libertas reports carrier off (link down) while scanning,
so that should mean the watchdog does not fire. However:
1. The watchdog will only check the current link state, which might be
up again when it runs.
2. The watchdog assumes that TX queues only fill up in response to
packets sent by the TX scheduler.
[...]
> Is libertas doing something wrong, or is this a bug/oddity in the network layer?
Since the TX scheduler doesn't know about the extra packets you are
injecting to do channel scanning, I think you need to call
txq_trans_update() when you do that. And I don't think it's a good idea
to call netif_carrier_off() there at all. If it has any effect at all
(which I don't think it will, as channel scanning is being done under
RTNL lock and link change notifications also require that lock) it will
be to confuse userland.
> Also, while looking at this code, I spotted a bug in dev_watchdog():
> /*
> * old device drivers set dev->trans_start
> */
> trans_start = txq->trans_start ? : dev->trans_start;
>
> i.e. it is trying to figure out whether to read trans_start from txq
> or dev. In both cases, trans_start is updated based on the value of
> jiffies, which will occasionally be 0 (as it wraps around). Therefore
> this line of code will occasionally make the wrong decision.
No, I don't think so.
If only dev->trans_start is being updated then the watchdog reads that.
If both txq->trans_start and dev->trans_start are being updated then it
doesn't matter much which the watchdog reads.
If only txq->trans_start is being updated then dev->trans_start is
always set to 0, so when txq->trans_start is 0 the watchdog still gets
0.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 0/3] net: Byte queue limit patch series
From: Tom Herbert @ 2011-05-02 2:41 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20110429.115443.28811990.davem@davemloft.net>
On Fri, Apr 29, 2011 at 11:54 AM, David Miller <davem@davemloft.net> wrote:
> From: Tom Herbert <therbert@google.com>
> Date: Mon, 25 Apr 2011 21:38:06 -0700 (PDT)
>
>> This patch series implements byte queue limits (bql) for NIC TX queues.
>
> I like the idea, I don't like how much drivers have to be involved
> in this.
>
> TX queue handling is already too involved for driver writers, so
> having them need to get all of these new hooks right is a non-starter.
>
> I don't even think it's necessary to be honest, I think you can hide
> to bulk of it.
>
> alloc_etherdev_mq() can initialize the per-txq bql instances.
>
> Add new interface, netdev_free_tx_skb(txq, skb) which can do the
> completion accounting. Actually the 'txq' argument is probably
> superfluous as it can be obtained from the skb itself.
>
Okay, but I think the call at the end of TX completion processing is
still probably needed. The algorithm is trying to determine the
number of bytes that completed at each interrupt.
> dev_hard_start_xmit() can do the "sent" processing.
>
> Then the only thing you're doing is replacing dev_kfree_skb*()
> in the TX path of the driver with the new netdev_free_tx_skb()
> thing.
>
> Maybe you can add a "netdev_tx_queue_reset()" hook for asynchronous
> device resets. Otherwise the bql reset can occur in generic code
> right at ->ndo_open().
>
Reset probably isn't necessary anyway if all the skb's are properly
completed with netdev_free_tx_skb.
> Finally, you manage the bql limit logic in the existing generic netdev
> TX start/stop interfaces. If the user asks for "start" but the bql
> is overlimit, simply ignore the request. The driver will just signal
> another "start" when the next TX packet completes.
>
> Similarly, when the qdisc is queuing up a packet to
> dev_hard_start_xmit() you can, for example, preemptively do a "stop"
> on the queue if you find bql is overlimit.
>
Unfortunately, there is still an additional complexity if we don't
piggy back on the logic in the driver to stop the queue. I believe
that either this would require another queue state for queue being
stopped for bql which looks pretty cumbersome, so that wrapping this
in a qdisc might be a better possibility.
Tom
> Thanks Tom.
>
>
^ permalink raw reply
* Re: [PATCH 0/3] net: Byte queue limit patch series
From: David Miller @ 2011-05-02 3:49 UTC (permalink / raw)
To: therbert; +Cc: netdev
In-Reply-To: <BANLkTinFmfJbYxvZ+6rrAy+6XsfwF5an5Q@mail.gmail.com>
From: Tom Herbert <therbert@google.com>
Date: Sun, 1 May 2011 19:41:34 -0700
> On Fri, Apr 29, 2011 at 11:54 AM, David Miller <davem@davemloft.net> wrote:
>> Add new interface, netdev_free_tx_skb(txq, skb) which can do the
>> completion accounting. Actually the 'txq' argument is probably
>> superfluous as it can be obtained from the skb itself.
>>
> Okay, but I think the call at the end of TX completion processing is
> still probably needed. The algorithm is trying to determine the
> number of bytes that completed at each interrupt.
Ok, then call it something generic like netdev_tx_complete() which
can serve other purposes in the future and not be bql specific.
>> Finally, you manage the bql limit logic in the existing generic netdev
>> TX start/stop interfaces. If the user asks for "start" but the bql
>> is overlimit, simply ignore the request. The driver will just signal
>> another "start" when the next TX packet completes.
>>
>> Similarly, when the qdisc is queuing up a packet to
>> dev_hard_start_xmit() you can, for example, preemptively do a "stop"
>> on the queue if you find bql is overlimit.
>>
> Unfortunately, there is still an additional complexity if we don't
> piggy back on the logic in the driver to stop the queue. I believe
> that either this would require another queue state for queue being
> stopped for bql which looks pretty cumbersome, so that wrapping this
> in a qdisc might be a better possibility.
I'll leave it up to you what approach to try next.
Even thought I sort of side with you that bql is a largely seperate
facility from what we usually do with qdiscs, this TX completion
event could be very useful as an input to qdisc decision making.
^ permalink raw reply
* Re: [PATCH] af_unix: Only allow recv on connected seqpacket sockets.
From: David Miller @ 2011-05-02 6:16 UTC (permalink / raw)
To: ebiederm; +Cc: netdev, xemul, dan, stable
In-Reply-To: <m1tydmo19o.fsf@fess.ebiederm.org>
From: ebiederm@xmission.com (Eric W. Biederman)
Date: Mon, 25 Apr 2011 07:26:27 -0700
> When the other socket in an established connection calls unix_shutdown
> or unix_release_sock. sk->sk_shutdown is changed, but sk_state is
> left at TCP_ESTABLISHED. Therefore we do not need a special
> case in unix_seqpacket_recvmsg to handle the RCV_SHUTDOWN case
> because in any case where that applies we will be in TCP_ESTABLISHED
> and we will simply call unix_dgram_recvmsg.
Thanks for explaining Eric, patch applied.
^ permalink raw reply
* Re: [PATCH] ipv4: don't spam dmesg with "Using LC-trie" messages
From: David Miller @ 2011-05-02 6:18 UTC (permalink / raw)
To: adobriyan; +Cc: netdev
In-Reply-To: <20110501120411.GA5224@p183>
From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Sun, 1 May 2011 15:04:11 +0300
> fib_trie_table() is called during netns creation and
> Chromium uses clone(CLONE_NEWNET) to sandbox renderer process.
>
> Don't print anything.
>
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Yeah that's pretty annoying, patch applied, thanks.
^ permalink raw reply
* Re: [PATCHv2 2/2] tg3: Add code to allow ethtool to enable/disable loopback.
From: Joe Perches @ 2011-05-02 6:29 UTC (permalink / raw)
To: Mahesh Bandewar
Cc: David Miller, Matt Carlson, netdev, Michael Chan, Ben Hutchings,
Michał Mirosław
In-Reply-To: <1304125404-19376-1-git-send-email-maheshb@google.com>
On Fri, 2011-04-29 at 18:03 -0700, Mahesh Bandewar wrote:
> Signed-off-by: Mahesh Bandewar <maheshb@google.com>
trivia:
> drivers/net/tg3.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++
[]
> @@ -15241,6 +15288,16 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
> dev->features |= hw_features;
> dev->vlan_features |= hw_features;
>
> + /*
> + * Add loopback capability only for a subset of devices that support
> + * MAC-LOOPBACK. Eventually this need to be enhanced to allow INT-PHY
> + * loopback for the remaining devices.
> + */
> + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780 ||
> + !tg3_flag(tp, CPMU_PRESENT))
The indentation style is a bit out of character for the file.
Aligned to open parenthesis is the style used elsewhere:
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780 ||
!tg3_flag(tp, CPMU_PRESENT))
like this:
> if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 &&
> !tg3_flag(tp, TSO_CAPABLE) &&
> !(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH)) {
^ permalink raw reply
* [PATCH] linux/stmmac.h: include <linux/platform_device.h> to remove compilation warning.
From: Viresh Kumar @ 2011-05-02 6:30 UTC (permalink / raw)
To: peppe.cavallaro
Cc: netdev, shiraz.hashim, armando.visconti, deepak.sikri,
viresh.linux, Viresh Kumar
stmmac.h uses struct platform_device and doesn't include
<linux/platform_device.h>. And so we get following compilation warning while
using this file:
warning: ‘struct platform_device’ declared inside parameter list
This patch includes <linux/platform_device.h> in stmmac.h to remove this warning
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
include/linux/stmmac.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 73d9b4e..d7dfe7d 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -26,6 +26,8 @@
#ifndef __STMMAC_PLATFORM_DATA
#define __STMMAC_PLATFORM_DATA
+#include <linux/platform_device.h>
+
#define STMAC_TYPE_0 0
#define STMAC_TYPE_1 1
#define STMAC_TYPE_2 2
--
1.7.2.2
^ permalink raw reply related
* Re: [PATCH v4 2/5] can: add rtnetlink support
From: Kurt Van Dijck @ 2011-05-02 7:36 UTC (permalink / raw)
To: Oliver Hartkopp
Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <4DBD9586.7080908-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>
On Sun, May 01, 2011 at 07:16:54PM +0200, Oliver Hartkopp wrote:
> On 27.04.2011 10:57, Kurt Van Dijck wrote:
> Hello Kurt,
>
> i applied all your patches for the can-utils and the network layer stuff to
> the BerliOS SVN in socketcan/branches/j1939 for testing.
A branch looks like a good alternative here.
Thanks.
>
>
[...]
> As it is pretty easy now to build the kernel modules & your provided can-utils
> we hopefully get some more feedback from j1939 users.
Ok. I'm curious...
>
> Best regards,
> Oliver
Kurt
^ permalink raw reply
* Re: [PATCH V3 2/8] Add a new zerocopy device flag
From: Michael S. Tsirkin @ 2011-05-02 10:42 UTC (permalink / raw)
To: Shirley Ma
Cc: David Miller, Eric Dumazet, Avi Kivity, Arnd Bergmann, netdev,
kvm, linux-kernel
In-Reply-To: <1303328648.19336.24.camel@localhost.localdomain>
On Wed, Apr 20, 2011 at 12:44:08PM -0700, Shirley Ma wrote:
> This zerocopy flag is used to support device DMA userspace buffers.
>
> Signed-off-by: Shirley Ma <xma@us.ibm.com>
> ---
>
> include/linux/netdevice.h | 3 +++
> 1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 0249fe7..0998d3d 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -1067,6 +1067,9 @@ struct net_device {
> #define NETIF_F_RXHASH (1 << 28) /* Receive hashing offload */
> #define NETIF_F_RXCSUM (1 << 29) /* Receive checksumming offload */
>
> +/* bit 29 is for device to map userspace buffers -- zerocopy */
This comment should specify what exactly is the promise the
device makes by setting this flag. Specifically, the
condition is that no skb fragments are used
after the uinfo callback has been called.
The way it's implemented, it probably means the device
should not use any of skb_clone, expand head etc.
> +#define NETIF_F_ZEROCOPY (1 << 29)
> +
> /* Segmentation offload features */
> #define NETIF_F_GSO_SHIFT 16
> #define NETIF_F_GSO_MASK 0x00ff0000
>
^ permalink raw reply
* Re: [PATCH V3 3/8] Add userspace buffers support in skb
From: Michael S. Tsirkin @ 2011-05-02 10:53 UTC (permalink / raw)
To: Shirley Ma
Cc: David Miller, Eric Dumazet, Avi Kivity, Arnd Bergmann, netdev,
kvm, linux-kernel
In-Reply-To: <1303328877.19336.28.camel@localhost.localdomain>
On Wed, Apr 20, 2011 at 12:47:57PM -0700, Shirley Ma wrote:
> This patch adds userspace buffers support in skb. A new struct
> skb_ubuf_info is needed to maintain the userspace buffers argument
> and index, a callback is used to notify userspace to release the
> buffers once lower device has done DMA (Last reference to that skb
> has gone).
>
> Signed-off-by: Shirley Ma <xma@us.ibm.com>
> ---
>
> include/linux/skbuff.h | 14 ++++++++++++++
> net/core/skbuff.c | 15 ++++++++++++++-
> 2 files changed, 28 insertions(+), 1 deletions(-)
>
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index d0ae90a..47a187b 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -189,6 +189,16 @@ enum {
> SKBTX_DRV_NEEDS_SK_REF = 1 << 3,
> };
>
> +/* The callback notifies userspace to release buffers when skb DMA is done in
> + * lower device, the desc is used to track userspace buffer index.
> + */
> +struct skb_ubuf_info {
> + /* support buffers allocation from userspace */
> + void (*callback)(struct sk_buff *);
> + void *arg;
> + size_t desc;
> +};
> +
> /* This data is invariant across clones and lives at
> * the end of the header data, ie. at skb->end.
> */
> @@ -211,6 +221,10 @@ struct skb_shared_info {
> /* Intermediate layers must ensure that destructor_arg
> * remains valid until skb destructor */
> void * destructor_arg;
> +
> + /* DMA mapping from/to userspace buffers */
> + struct skb_ubuf_info ubuf;
> +
> /* must be last field, see pskb_expand_head() */
> skb_frag_t frags[MAX_SKB_FRAGS];
> };
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index 7ebeed0..822c07d 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -210,6 +210,8 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
> shinfo = skb_shinfo(skb);
> memset(shinfo, 0, offsetof(struct skb_shared_info, dataref));
> atomic_set(&shinfo->dataref, 1);
> + shinfo->ubuf.callback = NULL;
> + shinfo->ubuf.arg = NULL;
> kmemcheck_annotate_variable(shinfo->destructor_arg);
>
> if (fclone) {
> @@ -327,7 +329,15 @@ static void skb_release_data(struct sk_buff *skb)
> for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
> put_page(skb_shinfo(skb)->frags[i].page);
> }
> -
> + /*
> + * if skb buf is from userspace, we need to notify the caller
> + * the lower device DMA has done;
> + */
> + if (skb_shinfo(skb)->ubuf.callback) {
> + skb_shinfo(skb)->ubuf.callback(skb);
> + skb_shinfo(skb)->ubuf.callback = NULL;
> + skb_shinfo(skb)->ubuf.arg = NULL;
> + }
> if (skb_has_frag_list(skb))
> skb_drop_fraglist(skb);
>
We probably don't need to touch arg if callback is NULL?
> @@ -480,6 +490,9 @@ bool skb_recycle_check(struct sk_buff *skb, int skb_size)
> if (irqs_disabled())
> return false;
>
> + if (shinfo->ubuf.callback)
> + return false;
> +
> if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE)
> return false;
This is not the only API unsupported for these skbs, is it?
Probably need to check and fail there as well.
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [v4 PATCH 1/6] IPVS: Change of socket usage to enable name space exit.
From: Simon Horman @ 2011-05-02 11:03 UTC (permalink / raw)
To: Hans Schillstrom
Cc: ja, ebiederm, lvs-devel, netdev, netfilter-devel,
hans.schillstrom
In-Reply-To: <1304268618-18103-2-git-send-email-hans@schillstrom.com>
On Sun, May 01, 2011 at 06:50:13PM +0200, Hans Schillstrom wrote:
> To work this patch also needs the other patches in this series.
Hi Hans,
could you explain the implications statement above?
What kind of behaviour might I expect if only this patch is applied?
I'm planning to push this and 2/6 for 2.6.39, and as we have
discussed (offline) that combination works. But from a bisection
point of view, this patch needs to not "blow up" if used by itself.
^ permalink raw reply
* Re: Re: [v4 PATCH 1/6] IPVS: Change of socket usage to enable name space exit.
From: Hans Schillstrom @ 2011-05-02 11:40 UTC (permalink / raw)
To: Simon Horman
Cc: ja, ebiederm, lvs-devel, netdev, netfilter-devel,
hans.schillstrom
>Sent: Mon, May 2, 2011, 13:03 PM
>Subject: Re: [v4 PATCH 1/6] IPVS: Change of socket usage to enable name space exit.
>
>On Sun, May 01, 2011 at 06:50:13PM +0200, Hans Schillstrom wrote:
>> To work this patch also needs the other patches in this series.
>
>Hi Hans,
>
>could you explain the implications statement above?
>What kind of behaviour might I expect if only this patch is applied?
Oops, left there by misstake.
Can you remove that line before pushing it ?
>I'm planning to push this and 2/6 for 2.6.39, and as we have
>discussed (offline) that combination works. But from a bisection
>point of view, this patch needs to not "blow up" if used by itself.
It should not be any bisect. problems from what I can see.
Regards
Hans
^ permalink raw reply
* Re: Re: [v4 PATCH 1/6] IPVS: Change of socket usage to enable name space exit.
From: Simon Horman @ 2011-05-02 12:26 UTC (permalink / raw)
To: Hans Schillstrom
Cc: ja, ebiederm, lvs-devel, netdev, netfilter-devel,
hans.schillstrom
In-Reply-To: <kqgtk9j.d83e4dced2edb2820c7e6329f634bb3f@obelix.schillstrom.com>
On Mon, May 02, 2011 at 01:40:04PM +0200, Hans Schillstrom wrote:
> >Sent: Mon, May 2, 2011, 13:03 PM
> >Subject: Re: [v4 PATCH 1/6] IPVS: Change of socket usage to enable name space exit.
> >
> >On Sun, May 01, 2011 at 06:50:13PM +0200, Hans Schillstrom wrote:
> >> To work this patch also needs the other patches in this series.
> >
> >Hi Hans,
> >
> >could you explain the implications statement above?
> >What kind of behaviour might I expect if only this patch is applied?
>
> Oops, left there by misstake.
> Can you remove that line before pushing it ?
Will do.
> >I'm planning to push this and 2/6 for 2.6.39, and as we have
> >discussed (offline) that combination works. But from a bisection
> >point of view, this patch needs to not "blow up" if used by itself.
>
> It should not be any bisect. problems from what I can see.
Thanks
^ 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