* Re: [PATCH net-next] scm: Don't use struct ucred in NETLINK_CB and struct scm_cookie.
From: Eric Dumazet @ 2012-09-07 15:07 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: David Miller, netdev, Serge E. Hallyn
In-Reply-To: <87haralb0u.fsf@xmission.com>
On Thu, 2012-09-06 at 21:20 -0700, Eric W. Biederman wrote:
> Passing uids and gids on NETLINK_CB from a process in one user
> namespace to a process in another user namespace can result in the
> wrong uid or gid being presented to userspace. Avoid that problem by
> passing kuids and kgids instead.
>
> - define struct scm_creds for use in scm_cookie and netlink_skb_parms
> that holds uid and gid information in kuid_t and kgid_t.
>
> - Modify scm_set_cred to fill out scm_creds by heand instead of using
> cred_to_ucred to fill out struct ucred. This conversion ensures
> userspace does not get incorrect uid or gid values to look at.
>
> - Modify scm_recv to convert from struct scm_creds to struct ucred
> before copying credential values to userspace.
>
> - Modify __scm_send to populate struct scm_creds on in the scm_cookie,
> instead of just copying struct ucred from userspace.
>
> - Modify netlink_sendmsg to copy scm_creds instead of struct ucred
> into the NETLINK_CB.
>
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
> index 7cb7867..6473267 100644
> --- a/net/netlink/af_netlink.c
> +++ b/net/netlink/af_netlink.c
> @@ -1398,7 +1398,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
>
> NETLINK_CB(skb).pid = nlk->pid;
> NETLINK_CB(skb).dst_group = dst_group;
> - memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
> + NETLINK_CB(skb).creds = siocb->scm->creds;
>
> err = -EFAULT;
> if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
Seems fine to me, but I am not sure why you kept NETLINK_CREDS()
defined/used once.
^ permalink raw reply
* Re: [PATCH 0/5] dev_<level> and dynamic_debug cleanups
From: Joe Perches @ 2012-09-07 14:58 UTC (permalink / raw)
To: Jason Baron
Cc: Andrew Morton, netdev, Greg Kroah-Hartman, David S. Miller,
Jim Cromie, Kay Sievers, linux-kernel
In-Reply-To: <1346957026.13424.5.camel@joe2Laptop>
On Thu, 2012-09-06 at 11:43 -0700, Joe Perches wrote:
> On Thu, 2012-09-06 at 13:51 -0400, Jason Baron wrote:
> > On Sun, Aug 26, 2012 at 04:25:25AM -0700, Joe Perches wrote:
> > > The recent commit to fix dynamic_debug was a bit unclean.
> > > Neaten the style for dynamic_debug.
> > > Reduce the stack use of message logging that uses netdev_printk
> > > Add utility functions dev_printk_emit and dev_vprintk_emit for /dev/kmsg.
[]
> > The one thing that is bothering me though, is that for
> > __dynamic_dev_dbg(), __dynamic_netdev_dbg(), we are copying much of the core
> > logic of __dev_printk(), __netdev_printk(), respectively. I would prefer
> > have this in one place. Can we add a 'prefix' argument to __dev_printk(),
> > and __netdev_printk() that dynamic debug can use, but is simply empty
> > for dev_printk() and netdev_printk().
>
> I don't think that's an improvement actually.
Because it would add an always effectively unused "" argument
to dev_printk and netdev_printk calls in non dynamic_debug
builds.
dynamic_debug is still mostly a developer feature and I
believe most distros do not enable it.
^ permalink raw reply
* Re: [PATCH 0/5] dev_<level> and dynamic_debug cleanups
From: Jason Baron @ 2012-09-07 14:52 UTC (permalink / raw)
To: Joe Perches
Cc: Andrew Morton, netdev, Greg Kroah-Hartman, David S. Miller,
Jim Cromie, Kay Sievers, linux-kernel
In-Reply-To: <1346957026.13424.5.camel@joe2Laptop>
On Thu, Sep 06, 2012 at 11:43:46AM -0700, Joe Perches wrote:
> On Thu, 2012-09-06 at 13:51 -0400, Jason Baron wrote:
> > On Sun, Aug 26, 2012 at 04:25:25AM -0700, Joe Perches wrote:
> > > The recent commit to fix dynamic_debug was a bit unclean.
> > > Neaten the style for dynamic_debug.
> > > Reduce the stack use of message logging that uses netdev_printk
> > > Add utility functions dev_printk_emit and dev_vprintk_emit for /dev/kmsg.
> > >
> > > Joe Perches (5):
> > > dev_dbg/dynamic_debug: Update to use printk_emit, optimize stack
> > > netdev_printk/dynamic_netdev_dbg: Directly call printk_emit
> > > netdev_printk/netif_printk: Remove a superfluous logging colon
> > > dev: Add dev_vprintk_emit and dev_printk_emit
> > > device and dynamic_debug: Use dev_vprintk_emit and dev_printk_emit
> > >
> >
> > Looks Good.
> >
> > The one thing that is bothering me though, is that for
> > __dynamic_dev_dbg(), __dynamic_netdev_dbg(), we are copying much of the core
> > logic of __dev_printk(), __netdev_printk(), respectively. I would prefer
> > have this in one place. Can we add a 'prefix' argument to __dev_printk(),
> > and __netdev_printk() that dynamic debug can use, but is simply empty
> > for dev_printk() and netdev_printk().
>
> I don't think that's an improvement actually.
> Why don't you try it.
>
Ok, below is what I was thinking. It winds up being more deletions than
insertions.
Thanks,
-Jason
dynamic debug: remove duplicate __netdev_printk() and __dev_printk() logic
Add an option prefix string argument to __netdev_printk() and __dev_printk().
In this way dynamic debug does not have to contain duplicate logic.
Signed-off-by: Jason Baron <jbaron@redhat.com>
---
drivers/base/core.c | 13 +++++++------
include/linux/device.h | 3 +++
include/linux/netdevice.h | 3 +++
lib/dynamic_debug.c | 32 ++++++++------------------------
net/core/dev.c | 11 ++++++-----
5 files changed, 27 insertions(+), 35 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 65f82e3..7b4ee6d 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1937,15 +1937,16 @@ int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...)
}
EXPORT_SYMBOL(dev_printk_emit);
-static int __dev_printk(const char *level, const struct device *dev,
- struct va_format *vaf)
+int __dev_printk(const char *level, const struct device *dev,
+ char *prefix, struct va_format *vaf)
{
if (!dev)
return printk("%s(NULL device *): %pV", level, vaf);
return dev_printk_emit(level[1] - '0', dev,
- "%s %s: %pV",
- dev_driver_string(dev), dev_name(dev), vaf);
+ "%s%s %s: %pV",
+ prefix, dev_driver_string(dev),
+ dev_name(dev), vaf);
}
int dev_printk(const char *level, const struct device *dev,
@@ -1960,7 +1961,7 @@ int dev_printk(const char *level, const struct device *dev,
vaf.fmt = fmt;
vaf.va = &args;
- r = __dev_printk(level, dev, &vaf);
+ r = __dev_printk(level, dev, "", &vaf);
va_end(args);
@@ -1980,7 +1981,7 @@ int func(const struct device *dev, const char *fmt, ...) \
vaf.fmt = fmt; \
vaf.va = &args; \
\
- r = __dev_printk(kern_level, dev, &vaf); \
+ r = __dev_printk(kern_level, dev, "", &vaf); \
\
va_end(args); \
\
diff --git a/include/linux/device.h b/include/linux/device.h
index 2da4589..573b15e 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -891,6 +891,9 @@ extern const char *dev_driver_string(const struct device *dev);
#ifdef CONFIG_PRINTK
+extern int __dev_printk(const char *level, const struct device *dev,
+ char *prefix, struct va_format *vaf);
+
extern int dev_vprintk_emit(int level, const struct device *dev,
const char *fmt, va_list args);
extern __printf(3, 4)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 5f49cc0..63f6165 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2720,6 +2720,9 @@ static inline const char *netdev_name(const struct net_device *dev)
return dev->name;
}
+extern int __netdev_printk(const char *level, const struct net_device *dev,
+ char *prefix, struct va_format *vaf);
+
extern __printf(3, 4)
int netdev_printk(const char *level, const struct net_device *dev,
const char *format, ...);
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index e7f7d99..83bf601 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -578,6 +578,7 @@ int __dynamic_dev_dbg(struct _ddebug *descriptor,
struct va_format vaf;
va_list args;
int res;
+ char buf[PREFIX_SIZE];
BUG_ON(!descriptor);
BUG_ON(!fmt);
@@ -587,16 +588,9 @@ int __dynamic_dev_dbg(struct _ddebug *descriptor,
vaf.fmt = fmt;
vaf.va = &args;
- if (!dev) {
- res = printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
- } else {
- char buf[PREFIX_SIZE];
-
- res = dev_printk_emit(7, dev, "%s%s %s: %pV",
- dynamic_emit_prefix(descriptor, buf),
- dev_driver_string(dev), dev_name(dev),
- &vaf);
- }
+ res = __dev_printk(KERN_DEBUG, dev,
+ dynamic_emit_prefix(descriptor, buf),
+ &vaf);
va_end(args);
@@ -612,6 +606,7 @@ int __dynamic_netdev_dbg(struct _ddebug *descriptor,
struct va_format vaf;
va_list args;
int res;
+ char buf[PREFIX_SIZE];
BUG_ON(!descriptor);
BUG_ON(!fmt);
@@ -621,20 +616,9 @@ int __dynamic_netdev_dbg(struct _ddebug *descriptor,
vaf.fmt = fmt;
vaf.va = &args;
- if (dev && dev->dev.parent) {
- char buf[PREFIX_SIZE];
-
- res = dev_printk_emit(7, dev->dev.parent,
- "%s%s %s %s: %pV",
- dynamic_emit_prefix(descriptor, buf),
- dev_driver_string(dev->dev.parent),
- dev_name(dev->dev.parent),
- netdev_name(dev), &vaf);
- } else if (dev) {
- res = printk(KERN_DEBUG "%s: %pV", netdev_name(dev), &vaf);
- } else {
- res = printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
- }
+ res = __netdev_printk(KERN_DEBUG, dev,
+ dynamic_emit_prefix(descriptor, buf),
+ &vaf);
va_end(args);
diff --git a/net/core/dev.c b/net/core/dev.c
index 8ad42fd..5fef0f6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6422,15 +6422,16 @@ const char *netdev_drivername(const struct net_device *dev)
return empty;
}
-static int __netdev_printk(const char *level, const struct net_device *dev,
- struct va_format *vaf)
+int __netdev_printk(const char *level, const struct net_device *dev,
+ char *prefix, struct va_format *vaf)
{
int r;
if (dev && dev->dev.parent) {
r = dev_printk_emit(level[1] - '0',
dev->dev.parent,
- "%s %s %s: %pV",
+ "%s%s %s %s: %pV",
+ prefix,
dev_driver_string(dev->dev.parent),
dev_name(dev->dev.parent),
netdev_name(dev), vaf);
@@ -6455,7 +6456,7 @@ int netdev_printk(const char *level, const struct net_device *dev,
vaf.fmt = format;
vaf.va = &args;
- r = __netdev_printk(level, dev, &vaf);
+ r = __netdev_printk(level, dev, "", &vaf);
va_end(args);
@@ -6475,7 +6476,7 @@ int func(const struct net_device *dev, const char *fmt, ...) \
vaf.fmt = fmt; \
vaf.va = &args; \
\
- r = __netdev_printk(level, dev, &vaf); \
+ r = __netdev_printk(level, dev, "", &vaf); \
\
va_end(args); \
\
--
1.7.7.6
^ permalink raw reply related
* Re: [PATCH 1/2] dst: take into account policy update on check()
From: Vlad Yasevich @ 2012-09-07 14:51 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Nicolas Dichtel, davem, sri, linux-sctp, netdev
In-Reply-To: <1347028510.2484.736.camel@edumazet-glaptop>
On 09/07/2012 10:35 AM, Eric Dumazet wrote:
> On Fri, 2012-09-07 at 17:57 +0200, Nicolas Dichtel wrote:
>> When a xfrm policy is inserted or deleted, we must invalidate
>> all dst and recalculate the route.
>>
>> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
>> ---
>> include/net/dst.h | 7 +++++++
>> net/core/dst.c | 1 +
>> net/core/sock.c | 4 ++--
>> net/ipv6/ip6_tunnel.c | 3 +--
>> 4 files changed, 11 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/net/dst.h b/include/net/dst.h
>> index 9a78810..478e55a 100644
>> --- a/include/net/dst.h
>> +++ b/include/net/dst.h
>> @@ -101,6 +101,9 @@ struct dst_entry {
>> atomic_t __refcnt; /* client references */
>> int __use;
>> unsigned long lastuse;
>> +#ifdef CONFIG_XFRM
>> + u32 flow_cache_genid;
>> +#endif
>> union {
>> struct dst_entry *next;
>> struct rtable __rcu *rt_next;
>> @@ -457,6 +460,10 @@ static inline int dst_input(struct sk_buff *skb)
>>
>> static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie)
>> {
>> +#ifdef CONFIG_XFRM
>> + if (dst->flow_cache_genid != atomic_read(&flow_cache_genid))
>> + return NULL;
>> +#endif
>
> Hmm... cant we reuse rt_genid ?
>
> (When changing flow_cache_genid, change &net->ipv4.rt_genid)
>
I thought of that too, but that requires hacking xfrm to know the
namespace at the time it changes the flow_cache_genid. This one seems
simpler to do.
-vlad
^ permalink raw reply
* Re: [PATCH 1/2] dst: take into account policy update on check()
From: Nicolas Dichtel @ 2012-09-07 14:47 UTC (permalink / raw)
To: Eric Dumazet; +Cc: vyasevich, davem, sri, linux-sctp, netdev
In-Reply-To: <1347028510.2484.736.camel@edumazet-glaptop>
Le 07/09/2012 16:35, Eric Dumazet a écrit :
> On Fri, 2012-09-07 at 17:57 +0200, Nicolas Dichtel wrote:
>> When a xfrm policy is inserted or deleted, we must invalidate
>> all dst and recalculate the route.
>>
>> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
>> ---
>> include/net/dst.h | 7 +++++++
>> net/core/dst.c | 1 +
>> net/core/sock.c | 4 ++--
>> net/ipv6/ip6_tunnel.c | 3 +--
>> 4 files changed, 11 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/net/dst.h b/include/net/dst.h
>> index 9a78810..478e55a 100644
>> --- a/include/net/dst.h
>> +++ b/include/net/dst.h
>> @@ -101,6 +101,9 @@ struct dst_entry {
>> atomic_t __refcnt; /* client references */
>> int __use;
>> unsigned long lastuse;
>> +#ifdef CONFIG_XFRM
>> + u32 flow_cache_genid;
>> +#endif
>> union {
>> struct dst_entry *next;
>> struct rtable __rcu *rt_next;
>> @@ -457,6 +460,10 @@ static inline int dst_input(struct sk_buff *skb)
>>
>> static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie)
>> {
>> +#ifdef CONFIG_XFRM
>> + if (dst->flow_cache_genid != atomic_read(&flow_cache_genid))
>> + return NULL;
>> +#endif
>
> Hmm... cant we reuse rt_genid ?
>
> (When changing flow_cache_genid, change &net->ipv4.rt_genid)
And so adding a new field in net->ipv6?
Regards,
Nicolas
^ permalink raw reply
* Re: [PATCH 1/2] dst: take into account policy update on check()
From: Eric Dumazet @ 2012-09-07 14:35 UTC (permalink / raw)
To: Nicolas Dichtel; +Cc: vyasevich, davem, sri, linux-sctp, netdev
In-Reply-To: <1347033467-3757-2-git-send-email-nicolas.dichtel@6wind.com>
On Fri, 2012-09-07 at 17:57 +0200, Nicolas Dichtel wrote:
> When a xfrm policy is inserted or deleted, we must invalidate
> all dst and recalculate the route.
>
> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
> ---
> include/net/dst.h | 7 +++++++
> net/core/dst.c | 1 +
> net/core/sock.c | 4 ++--
> net/ipv6/ip6_tunnel.c | 3 +--
> 4 files changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/include/net/dst.h b/include/net/dst.h
> index 9a78810..478e55a 100644
> --- a/include/net/dst.h
> +++ b/include/net/dst.h
> @@ -101,6 +101,9 @@ struct dst_entry {
> atomic_t __refcnt; /* client references */
> int __use;
> unsigned long lastuse;
> +#ifdef CONFIG_XFRM
> + u32 flow_cache_genid;
> +#endif
> union {
> struct dst_entry *next;
> struct rtable __rcu *rt_next;
> @@ -457,6 +460,10 @@ static inline int dst_input(struct sk_buff *skb)
>
> static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie)
> {
> +#ifdef CONFIG_XFRM
> + if (dst->flow_cache_genid != atomic_read(&flow_cache_genid))
> + return NULL;
> +#endif
Hmm... cant we reuse rt_genid ?
(When changing flow_cache_genid, change &net->ipv4.rt_genid)
^ permalink raw reply
* Re: [PATCH 1/2] dst: take into account policy update on check()
From: Vlad Yasevich @ 2012-09-07 14:20 UTC (permalink / raw)
To: Nicolas Dichtel; +Cc: davem, sri, linux-sctp, netdev
In-Reply-To: <1347033467-3757-2-git-send-email-nicolas.dichtel@6wind.com>
On 09/07/2012 11:57 AM, Nicolas Dichtel wrote:
> When a xfrm policy is inserted or deleted, we must invalidate
> all dst and recalculate the route.
>
One suggestion may be to add an inline to get flow_cache_genid and then
you can get rid of #ifdefs in the code
Otherwise, this extends what IPv6 is doing to all protocols. Seem like
the right thing to do, but I'll let DaveM and others make the final
determination.
-vlad
> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
> ---
> include/net/dst.h | 7 +++++++
> net/core/dst.c | 1 +
> net/core/sock.c | 4 ++--
> net/ipv6/ip6_tunnel.c | 3 +--
> 4 files changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/include/net/dst.h b/include/net/dst.h
> index 9a78810..478e55a 100644
> --- a/include/net/dst.h
> +++ b/include/net/dst.h
> @@ -101,6 +101,9 @@ struct dst_entry {
> atomic_t __refcnt; /* client references */
> int __use;
> unsigned long lastuse;
> +#ifdef CONFIG_XFRM
> + u32 flow_cache_genid;
> +#endif
> union {
> struct dst_entry *next;
> struct rtable __rcu *rt_next;
> @@ -457,6 +460,10 @@ static inline int dst_input(struct sk_buff *skb)
>
> static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie)
> {
> +#ifdef CONFIG_XFRM
> + if (dst->flow_cache_genid != atomic_read(&flow_cache_genid))
> + return NULL;
> +#endif
> if (dst->obsolete)
> dst = dst->ops->check(dst, cookie);
> return dst;
> diff --git a/net/core/dst.c b/net/core/dst.c
> index f6593d2..19899d3 100644
> --- a/net/core/dst.c
> +++ b/net/core/dst.c
> @@ -181,6 +181,7 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
> dst->path = dst;
> #ifdef CONFIG_XFRM
> dst->xfrm = NULL;
> + dst->flow_cache_genid = atomic_read(&flow_cache_genid);
> #endif
> dst->input = dst_discard;
> dst->output = dst_discard;
> diff --git a/net/core/sock.c b/net/core/sock.c
> index d765156..1d06d4e 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -491,7 +491,7 @@ struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie)
> {
> struct dst_entry *dst = __sk_dst_get(sk);
>
> - if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
> + if (dst && dst_check(dst, cookie) == NULL) {
> sk_tx_queue_clear(sk);
> RCU_INIT_POINTER(sk->sk_dst_cache, NULL);
> dst_release(dst);
> @@ -506,7 +506,7 @@ struct dst_entry *sk_dst_check(struct sock *sk, u32 cookie)
> {
> struct dst_entry *dst = sk_dst_get(sk);
>
> - if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
> + if (dst && dst_check(dst, cookie) == NULL) {
> sk_dst_reset(sk);
> dst_release(dst);
> return NULL;
> diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
> index cb7e2de..e96431a 100644
> --- a/net/ipv6/ip6_tunnel.c
> +++ b/net/ipv6/ip6_tunnel.c
> @@ -130,8 +130,7 @@ struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t)
> {
> struct dst_entry *dst = t->dst_cache;
>
> - if (dst && dst->obsolete &&
> - dst->ops->check(dst, t->dst_cookie) == NULL) {
> + if (dst && dst_check(dst, t->dst_cookie) == NULL) {
> t->dst_cache = NULL;
> dst_release(dst);
> return NULL;
>
^ permalink raw reply
* [PATCH 2/2] ipv6: remove rt6i_flow_cache_genid field in rt6_info
From: Nicolas Dichtel @ 2012-09-07 15:57 UTC (permalink / raw)
To: vyasevich, davem; +Cc: sri, linux-sctp, netdev, Nicolas Dichtel
In-Reply-To: <1347033467-3757-1-git-send-email-nicolas.dichtel@6wind.com>
Now that flow_cache_genid is stored in dst, there is no need to add
specific code here.
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
include/net/ip6_fib.h | 3 ---
net/ipv6/inet6_connection_sock.c | 23 +----------------------
2 files changed, 1 insertion(+), 25 deletions(-)
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index cd64cf3..af11e95 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -112,9 +112,6 @@ struct rt6_info {
struct inet6_dev *rt6i_idev;
unsigned long _rt6i_peer;
-#ifdef CONFIG_XFRM
- u32 rt6i_flow_cache_genid;
-#endif
/* more non-fragment space at head required */
unsigned short rt6i_nfheader_len;
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 0251a60..c4f9341 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -175,33 +175,12 @@ void __inet6_csk_dst_store(struct sock *sk, struct dst_entry *dst,
const struct in6_addr *saddr)
{
__ip6_dst_store(sk, dst, daddr, saddr);
-
-#ifdef CONFIG_XFRM
- {
- struct rt6_info *rt = (struct rt6_info *)dst;
- rt->rt6i_flow_cache_genid = atomic_read(&flow_cache_genid);
- }
-#endif
}
static inline
struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
{
- struct dst_entry *dst;
-
- dst = __sk_dst_check(sk, cookie);
-
-#ifdef CONFIG_XFRM
- if (dst) {
- struct rt6_info *rt = (struct rt6_info *)dst;
- if (rt->rt6i_flow_cache_genid != atomic_read(&flow_cache_genid)) {
- __sk_dst_reset(sk);
- dst = NULL;
- }
- }
-#endif
-
- return dst;
+ return __sk_dst_check(sk, cookie);
}
static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
--
1.7.12
^ permalink raw reply related
* [PATCH 1/2] dst: take into account policy update on check()
From: Nicolas Dichtel @ 2012-09-07 15:57 UTC (permalink / raw)
To: vyasevich, davem; +Cc: sri, linux-sctp, netdev, Nicolas Dichtel
In-Reply-To: <1347033467-3757-1-git-send-email-nicolas.dichtel@6wind.com>
When a xfrm policy is inserted or deleted, we must invalidate
all dst and recalculate the route.
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
include/net/dst.h | 7 +++++++
net/core/dst.c | 1 +
net/core/sock.c | 4 ++--
net/ipv6/ip6_tunnel.c | 3 +--
4 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 9a78810..478e55a 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -101,6 +101,9 @@ struct dst_entry {
atomic_t __refcnt; /* client references */
int __use;
unsigned long lastuse;
+#ifdef CONFIG_XFRM
+ u32 flow_cache_genid;
+#endif
union {
struct dst_entry *next;
struct rtable __rcu *rt_next;
@@ -457,6 +460,10 @@ static inline int dst_input(struct sk_buff *skb)
static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie)
{
+#ifdef CONFIG_XFRM
+ if (dst->flow_cache_genid != atomic_read(&flow_cache_genid))
+ return NULL;
+#endif
if (dst->obsolete)
dst = dst->ops->check(dst, cookie);
return dst;
diff --git a/net/core/dst.c b/net/core/dst.c
index f6593d2..19899d3 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -181,6 +181,7 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
dst->path = dst;
#ifdef CONFIG_XFRM
dst->xfrm = NULL;
+ dst->flow_cache_genid = atomic_read(&flow_cache_genid);
#endif
dst->input = dst_discard;
dst->output = dst_discard;
diff --git a/net/core/sock.c b/net/core/sock.c
index d765156..1d06d4e 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -491,7 +491,7 @@ struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie)
{
struct dst_entry *dst = __sk_dst_get(sk);
- if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
+ if (dst && dst_check(dst, cookie) == NULL) {
sk_tx_queue_clear(sk);
RCU_INIT_POINTER(sk->sk_dst_cache, NULL);
dst_release(dst);
@@ -506,7 +506,7 @@ struct dst_entry *sk_dst_check(struct sock *sk, u32 cookie)
{
struct dst_entry *dst = sk_dst_get(sk);
- if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
+ if (dst && dst_check(dst, cookie) == NULL) {
sk_dst_reset(sk);
dst_release(dst);
return NULL;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index cb7e2de..e96431a 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -130,8 +130,7 @@ struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t)
{
struct dst_entry *dst = t->dst_cache;
- if (dst && dst->obsolete &&
- dst->ops->check(dst, t->dst_cookie) == NULL) {
+ if (dst && dst_check(dst, t->dst_cookie) == NULL) {
t->dst_cache = NULL;
dst_release(dst);
return NULL;
--
1.7.12
^ permalink raw reply related
* [PATCH RFC net-next 0/2] Take care of xfrm policy when checking dst entries
From: Nicolas Dichtel @ 2012-09-07 15:57 UTC (permalink / raw)
To: vyasevich, davem; +Cc: sri, linux-sctp, netdev
In-Reply-To: <5049FAE3.2050403@6wind.com>
The goal of these patches is to fix the following problem: a session is
established (TCP, SCTP) and after a new policy is inserted. The current
code does not recalculate the route, thus the traffic is not encrypted.
The patch propose to check flow_cache_genid value when checking a dst
entry, which is incremented each time a policy is inserted or deleted.
Patches are tested with TCP and SCTP.
Comments are welcome.
Regards,
Nicolas
^ permalink raw reply
* Re: [PATCH] sctp: check dst validity after IPsec operations
From: Nicolas Dichtel @ 2012-09-07 13:47 UTC (permalink / raw)
To: David Miller; +Cc: vyasevich, sri, linux-sctp, netdev
In-Reply-To: <20120906.141019.129727465932440024.davem@davemloft.net>
Le 06/09/2012 20:10, David Miller a écrit :
> From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
> Date: Thu, 6 Sep 2012 13:40:29 -0400
>
>> dst stored in struct sctp_transport needs to be recalculated when ipsec policy
>> are updated. We use flow_cache_genid for that.
>>
>> For example, if a SCTP connection is established and then an IPsec policy is
>> set, the old SCTP flow will not be updated and thus will not use the new
>> IPsec policy.
>>
>> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
>
> I don't like that SCTP need to perform special DST validation.
Ipv6 do the same:
inet6_csk_xmit()->inet6_csk_route_socket()->__inet6_csk_dst_check()
-> compare flow_cache_genid and rt6i_flow_cache_genid.
>
> The normal DST validation mechanism already in place should be
> sufficient.
I don't find why TCP recalculate the route, but it's not immediate, we should
wait a little.
>
> Otherwise this problem must exist in other protocols too, and
> fixing a tree wide issue privately inside of one protocol is
> not acceptable.
I will propose another patch.
Regards,
Nicolas
^ permalink raw reply
* RE: changing usbnet's API to better deal with cdc-ncm
From: Alexey ORISHKO @ 2012-09-07 13:10 UTC (permalink / raw)
To: Ming Lei
Cc: Oliver Neukum, bjorn@mork.no, netdev@vger.kernel.org,
linux-usb@vger.kernel.org, Alexey Orishko
In-Reply-To: <CACVXFVOmjvJQVWGzff_t7Hn7oAOxFzfV1CXyJWhuuBqjFcM3eQ@mail.gmail.com>
> -----Original Message-----
> From: Ming Lei [mailto:tom.leiming@gmail.com]
> Sent: Friday, September 07, 2012 2:58 PM
> > Several issues need to be improved:
> > Tx path:
> > 1. IP packets must be accumulated in one NTB. Currently it's done via
> data copy.
> > Preferred way would be a possibility to have a list of skb-s in
> resulting frame sent down.
>
> Looks the copy is inevitable because the buffer length of each skb in
> the list is not possible to be max endpoint packet aligned, so one
> short packet may terminate the current tx urb transfer.
Zero or short packet shall not be added if resulting NTB is max negotiated size.
It's yet another problem with usbnet, where we had to add some workarounds
to avoid redundant short/zero packets.
Regards,
Alexey
^ permalink raw reply
* Re: changing usbnet's API to better deal with cdc-ncm
From: Oliver Neukum @ 2012-09-07 13:08 UTC (permalink / raw)
To: Alexey ORISHKO
Cc: Bjørn Mork, Ming Lei,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <2AC7D4AD8BA1C640B4C60C61C8E520154A6AA5741E-8ZTw5gFVCTjVH5byLeRTJxkTb7+GphCuwzqs5ZKRSiY@public.gmane.org>
On Friday 07 September 2012 14:01:23 Alexey ORISHKO wrote:
> The experience from early implementations and prototyping of NCM was that
> using NCM with 4-8kB NTB increased max throughput in loop-mode by a factor
> of 5-6 even 8-10 times compared to using ECM. One real-world example was
> modem for 21+6Mbit/s what used 100% CPU with ECM responsible for approx. 40%
> of the MIPS used. Using NCM instead CPU was only at approx. 65% utilization.
> Which allowed multiple other functions to be added and significantly increased
> the usability and value of the modem.
>
> NCM efficiency is gained either by accessing TX queue of upper layer or
> by using timer.
>
> These findings were later confirmed by multiple major industry players
> (names withheld), and demonstrated during multiple NCM interoperability
> workshops using multiple device HW platforms, multiple operating systems
> and multiple host HW ranging from Beagleboard to latest quad-core x86.
>
> Until we do something with network device framework in order to get access
> to upper layer Tx queue we need to utilize timer.
Could you explain your reasoning? From what you say we must reduce the number
of transfers, thus use them efficiently, but why by means of a timer?
Regards
Oliver
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" 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: changing usbnet's API to better deal with cdc-ncm
From: Ming Lei @ 2012-09-07 12:58 UTC (permalink / raw)
To: Alexey ORISHKO
Cc: Oliver Neukum, bjorn@mork.no, netdev@vger.kernel.org,
linux-usb@vger.kernel.org, Alexey Orishko
In-Reply-To: <2AC7D4AD8BA1C640B4C60C61C8E520154A6AA56BF9@EXDCVYMBSTM006.EQ1STM.local>
On Thu, Sep 6, 2012 at 4:13 PM, Alexey ORISHKO
<alexey.orishko@stericsson.com> wrote:
>> -----Original Message-----
>> From: Oliver Neukum [mailto:oneukum@suse.de]
>
>
>> looking at cdc-ncm it seeems to me that cdc-ncm is forced to play very
>> dirty games because usbnet doesn't have a notion about aggregating
>> packets for a single transfer.
>
> Several issues need to be improved:
> Tx path:
> 1. IP packets must be accumulated in one NTB. Currently it's done via data copy.
> Preferred way would be a possibility to have a list of skb-s in resulting frame sent down.
Looks the copy is inevitable because the buffer length of each skb in the
list is not possible to be max endpoint packet aligned, so one short packet
may terminate the current tx urb transfer.
Thanks,
--
Ming Lei
^ permalink raw reply
* Re: [PATCH 1/4] slab: do ClearSlabPfmemalloc() for all pages of slab
From: Mel Gorman @ 2012-09-07 12:55 UTC (permalink / raw)
To: JoonSoo Kim
Cc: Andrew Morton, Linux-MM, Linux-Netdev, LKML, David Miller,
Chuck Lever, Pekka Enberg, David Rientjes, Christoph Lameter
In-Reply-To: <CAAmzW4MfFUH1Mi447sQvPNeae_BShEmbECUaK9eoX-8ughEdJw@mail.gmail.com>
On Fri, Sep 07, 2012 at 03:05:39AM +0900, JoonSoo Kim wrote:
> Correct Pekka's mail address and resend.
> Sorry.
>
> Add "Cc" to "Christoph Lameter" <cl@linux.com>
>
> 2012/9/5 Mel Gorman <mgorman@suse.de>:
> > Right now, we call ClearSlabPfmemalloc() for first page of slab when we
> > clear SlabPfmemalloc flag. This is fine for most swap-over-network use
> > cases as it is expected that order-0 pages are in use. Unfortunately it
> > is possible that that __ac_put_obj() checks SlabPfmemalloc on a tail page
> > and while this is harmless, it is sloppy. This patch ensures that the head
> > page is always used.
> >
> > This problem was originally identified by Joonsoo Kim.
> >
> > [js1304@gmail.com: Original implementation and problem identification]
> > Signed-off-by: Mel Gorman <mgorman@suse.de>
> > ---
> > mm/slab.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/mm/slab.c b/mm/slab.c
> > index 811af03..d34a903 100644
> > --- a/mm/slab.c
> > +++ b/mm/slab.c
> > @@ -1000,7 +1000,7 @@ static void *__ac_get_obj(struct kmem_cache *cachep, struct array_cache *ac,
> > l3 = cachep->nodelists[numa_mem_id()];
> > if (!list_empty(&l3->slabs_free) && force_refill) {
> > struct slab *slabp = virt_to_slab(objp);
> > - ClearPageSlabPfmemalloc(virt_to_page(slabp->s_mem));
> > + ClearPageSlabPfmemalloc(virt_to_head_page(slabp->s_mem));
> > clear_obj_pfmemalloc(&objp);
> > recheck_pfmemalloc_active(cachep, ac);
> > return objp;
>
> We assume that slabp->s_mem's address is always in head page, so
> "virt_to_head_page" is not needed.
>
Fair point. I thought it would be more "obvious" later that we really
always intended to use the head page but it is unnecessary.
> > @@ -1032,7 +1032,7 @@ static void *__ac_put_obj(struct kmem_cache *cachep, struct array_cache *ac,
> > {
> > if (unlikely(pfmemalloc_active)) {
> > /* Some pfmemalloc slabs exist, check if this is one */
> > - struct page *page = virt_to_page(objp);
> > + struct page *page = virt_to_head_page(objp);
> > if (PageSlabPfmemalloc(page))
> > set_obj_pfmemalloc(&objp);
> > }
> > --
> > 1.7.9.2
> >
>
> If we always use head page, following suggestion is more good to me.
> How about you?
>
> diff --git a/mm/slab.c b/mm/slab.c
> index f8b0d53..ce70989 100644
> --- a/mm/slab.c
> +++ b/mm/slab.c
> @@ -1032,7 +1032,7 @@ static void *__ac_put_obj(struct kmem_cache
> *cachep, struct array_cache *ac,
> {
> if (unlikely(pfmemalloc_active)) {
> /* Some pfmemalloc slabs exist, check if this is one */
> - struct page *page = virt_to_page(objp);
> + struct page *page = virt_to_head_page(objp);
> if (PageSlabPfmemalloc(page))
> set_obj_pfmemalloc(&objp);
> }
ok.
> @@ -1921,10 +1921,9 @@ static void *kmem_getpages(struct kmem_cache
> *cachep, gfp_t flags, int nodeid)
> NR_SLAB_UNRECLAIMABLE, nr_pages);
> for (i = 0; i < nr_pages; i++) {
> __SetPageSlab(page + i);
> -
> - if (page->pfmemalloc)
> - SetPageSlabPfmemalloc(page + i);
> }
> + if (page->pfmemalloc)
> + SetPageSlabPfmemalloc(page);
>
> if (kmemcheck_enabled && !(cachep->flags & SLAB_NOTRACK)) {
> kmemcheck_alloc_shadow(page, cachep->gfporder, flags, nodeid);
ok.
> @@ -1943,26 +1942,26 @@ static void *kmem_getpages(struct kmem_cache
> *cachep, gfp_t flags, int nodeid)
> */
> static void kmem_freepages(struct kmem_cache *cachep, void *addr)
> {
> - unsigned long i = (1 << cachep->gfporder);
> + int nr_pages = (1 << cachep->gfporder);
> + int i;
> struct page *page = virt_to_page(addr);
> - const unsigned long nr_freed = i;
>
> kmemcheck_free_shadow(page, cachep->gfporder);
>
> if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
> sub_zone_page_state(page_zone(page),
> - NR_SLAB_RECLAIMABLE, nr_freed);
> + NR_SLAB_RECLAIMABLE, nr_pages);
> else
> sub_zone_page_state(page_zone(page),
> - NR_SLAB_UNRECLAIMABLE, nr_freed);
> - while (i--) {
> - BUG_ON(!PageSlab(page));
> - __ClearPageSlabPfmemalloc(page);
> - __ClearPageSlab(page);
> - page++;
> + NR_SLAB_UNRECLAIMABLE, nr_pages);
> + for (i = 0; i < nr_pages; i++) {
> + BUG_ON(!PageSlab(page + i));
> + __ClearPageSlab(page + i);
> }
> + __ClearPageSlabPfmemalloc(page);
> +
> if (current->reclaim_state)
> - current->reclaim_state->reclaimed_slab += nr_freed;
> + current->reclaim_state->reclaimed_slab += nr_pages;
> free_pages((unsigned long)addr, cachep->gfporder);
> }
This churns code a lot more than is necessary. How about this as a
replacement patch?
---8<---
From: Joonsoo Kim <js1304@gmail.com>
Subject: [PATCH] slab: do ClearSlabPfmemalloc() for all pages of slab
Right now, we call ClearSlabPfmemalloc() for first page of slab when we
clear SlabPfmemalloc flag. This is fine for most swap-over-network use
cases as it is expected that order-0 pages are in use. Unfortunately it
is possible that that __ac_put_obj() checks SlabPfmemalloc on a tail page
and while this is harmless, it is sloppy. This patch ensures that the head
page is always used.
[mgorman@suse.de: Easier implementation, changelog cleanup]
Signed-off-by: Joonsoo Kim <js1304@gmail.com>
Signed-off-by: Mel Gorman <mgorman@suse.de>
---
mm/slab.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/mm/slab.c b/mm/slab.c
index 811af03..590d52a 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1032,7 +1032,7 @@ static void *__ac_put_obj(struct kmem_cache *cachep, struct array_cache *ac,
{
if (unlikely(pfmemalloc_active)) {
/* Some pfmemalloc slabs exist, check if this is one */
- struct page *page = virt_to_page(objp);
+ struct page *page = virt_to_head_page(objp);
if (PageSlabPfmemalloc(page))
set_obj_pfmemalloc(&objp);
}
@@ -1919,12 +1919,10 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid)
else
add_zone_page_state(page_zone(page),
NR_SLAB_UNRECLAIMABLE, nr_pages);
- for (i = 0; i < nr_pages; i++) {
+ for (i = 0; i < nr_pages; i++)
__SetPageSlab(page + i);
-
- if (page->pfmemalloc)
- SetPageSlabPfmemalloc(page + i);
- }
+ if (page->pfmemalloc)
+ SetPageSlabPfmemalloc(page);
if (kmemcheck_enabled && !(cachep->flags & SLAB_NOTRACK)) {
kmemcheck_alloc_shadow(page, cachep->gfporder, flags, nodeid);
@@ -1955,9 +1953,9 @@ static void kmem_freepages(struct kmem_cache *cachep, void *addr)
else
sub_zone_page_state(page_zone(page),
NR_SLAB_UNRECLAIMABLE, nr_freed);
+ __ClearPageSlabPfmemalloc(page);
while (i--) {
BUG_ON(!PageSlab(page));
- __ClearPageSlabPfmemalloc(page);
__ClearPageSlab(page);
page++;
}
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* Re: [PATCH] sctp: check dst validity after IPsec operations
From: Nicolas Dichtel @ 2012-09-07 12:24 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: sri, linux-sctp, netdev
In-Reply-To: <5048D774.3020008@gmail.com>
Le 06/09/2012 19:03, Vlad Yasevich a écrit :
> On 09/06/2012 12:40 PM, Nicolas Dichtel wrote:
>> Le 06/09/2012 18:04, Vlad Yasevich a écrit :
>>> On 09/06/2012 01:40 PM, Nicolas Dichtel wrote:
>>>> dst stored in struct sctp_transport needs to be recalculated when
>>>> ipsec policy
>>>> are updated. We use flow_cache_genid for that.
>>>>
>>>> For example, if a SCTP connection is established and then an IPsec
>>>> policy is
>>>> set, the old SCTP flow will not be updated and thus will not use the new
>>>> IPsec policy.
>>>>
>>>> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
>>>
>>> why doesn't this need to be done for TCP? What makes SCTP special in
>>> this case?
>> Tests prove that the pb does not exist with TCP. I made the patch some
>> times ago, I will look again deeply to find the difference.
>>
>
> TCP appears to cache the flowi and uses that to re-route the packet.
> However, re-route still seems predicated on dst_check()...
Yes ... but I don't find the difference. Re-route is not done immediately in
TCP, it takes few seconds.
>
>>>
>>> ip_queue_xmit does an __sk_dst_check() which is essentially what
>>> sctp_transport_dst_check() does. That should determine if the
>>> currently cached
>>> route is valid or not.
>> The problem is that route will not be invalidated, because dst->check()
>> has no xfrm path so xfrm_dst_check() will never be called.
>>
>
> Shouldn't the cache be invalidated in this case? If the cache is invalidated,
> that should cause a new lookup. If the cache isn't invalidated, then any
> established connections that may now be impacted by the policy will not pick it up.
Yes, you're right. If I flush the cache manually (with the sysctl), route are
correctly updated.
I will send a new proposal.
Regards,
Nicolas
^ permalink raw reply
* Re: [PATCH] sctp: check dst validity after IPsec operations
From: Nicolas Dichtel @ 2012-09-07 12:07 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: sri, linux-sctp, netdev
In-Reply-To: <5048C984.3030306@gmail.com>
Le 06/09/2012 18:04, Vlad Yasevich a écrit :
> On 09/06/2012 01:40 PM, Nicolas Dichtel wrote:
>> dst stored in struct sctp_transport needs to be recalculated when ipsec policy
>> are updated. We use flow_cache_genid for that.
>>
>> For example, if a SCTP connection is established and then an IPsec policy is
>> set, the old SCTP flow will not be updated and thus will not use the new
>> IPsec policy.
>>
>> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
>
> why doesn't this need to be done for TCP? What makes SCTP special in this case?
>
> ip_queue_xmit does an __sk_dst_check() which is essentially what
> sctp_transport_dst_check() does. That should determine if the currently cached
> route is valid or not.
>
> Looks like sctp may need to change to using ip_route_output_ports() call
> as ip_route_output_key may not do all that is necessary
I try, but it doesn't solve the problem. In fact, it seems better to use
ip_route_output_ports(), would you like me to send a patch?
Regards,
Nicolas
^ permalink raw reply
* RE: changing usbnet's API to better deal with cdc-ncm
From: Alexey ORISHKO @ 2012-09-07 12:01 UTC (permalink / raw)
To: Oliver Neukum
Cc: Bjørn Mork, Ming Lei,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <1446113.XC2Qbo4flT-ugxBuEnWX9yG/4A2pS7c2Q@public.gmane.org>
> -----Original Message-----
> From: Oliver Neukum [mailto:oneukum-l3A5Bk7waGM@public.gmane.org]
> Sent: Friday, September 07, 2012 9:36 AM
> > > Well, that is the mistake. Using a timer is a bad idea.
> >
> > Why is a bad idea? Without a timer, how can usbnet or low level
> > driver aggregate the later coming transmit frames to form a biger
> > aggregated frame?
>
> By registering demand in an abstract sense. The timer makes sense only
> when no other buffers are being transfered.
>
> The timer means that we transmit if no other more packages are coming
> down from the upper layers. Now, either the device is still busy or it
> is not.
> While it is busy, we might just as well wait, because the upper layer
> may change its mind.
> If the device is not busy we worsen latency by waiting for the timer.
...
> > As I said above, without a timeout timer, the queued skb might not be
> > sent out even some long time passed if no frame comes later.
>
> Therefore we check whether the device is still busy.
>
The purpose of NCM is to reduce the amount of interrupts and the number
of DMA jobs that must be handled by the device. It is most efficient to
send and especially to receive NTBs of agreed size, padded if needed.
Misunderstanding of the reason why NCM protocol is doing aggregation
of several ETH frames into a single NTB leads to crippled implementation.
Look at NCM gadget, which is not really NCM device at all, it's kinda ECM
device with NCM framing.
The experience from early implementations and prototyping of NCM was that
using NCM with 4-8kB NTB increased max throughput in loop-mode by a factor
of 5-6 even 8-10 times compared to using ECM. One real-world example was
modem for 21+6Mbit/s what used 100% CPU with ECM responsible for approx. 40%
of the MIPS used. Using NCM instead CPU was only at approx. 65% utilization.
Which allowed multiple other functions to be added and significantly increased
the usability and value of the modem.
NCM efficiency is gained either by accessing TX queue of upper layer or
by using timer.
These findings were later confirmed by multiple major industry players
(names withheld), and demonstrated during multiple NCM interoperability
workshops using multiple device HW platforms, multiple operating systems
and multiple host HW ranging from Beagleboard to latest quad-core x86.
Until we do something with network device framework in order to get access
to upper layer Tx queue we need to utilize timer.
Regards,
Alexey
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" 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 8/10] net/mac80211/scan.c: removes unnecessary semicolon
From: Johannes Berg @ 2012-09-07 11:30 UTC (permalink / raw)
To: Peter Senna Tschudin
Cc: John W. Linville, kernel-janitors, David S. Miller,
linux-wireless, netdev, linux-kernel
In-Reply-To: <1346947757-10481-9-git-send-email-peter.senna@gmail.com>
On Thu, 2012-09-06 at 18:09 +0200, Peter Senna Tschudin wrote:
> From: Peter Senna Tschudin <peter.senna@gmail.com>
>
> removes unnecessary semicolon
>
> Found by Coccinelle: http://coccinelle.lip6.fr/
Applied. It'd be nice to have the spatch, I guess :)
johannes
^ permalink raw reply
* [PATCH net-next v2] ipv4/route: arg delay is useless in rt_cache_flush()
From: Nicolas Dichtel @ 2012-09-07 10:45 UTC (permalink / raw)
To: davem, eric.dumazet; +Cc: netdev, Nicolas Dichtel
In-Reply-To: <1347013794.2484.488.camel@edumazet-glaptop>
Since route cache deletion (89aef8921bfbac22f), delay is no
more used. Remove it.
v2: remove ctl in ipv4_sysctl_rtcache_flush()
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
include/net/route.h | 2 +-
net/ipv4/arp.c | 2 +-
net/ipv4/devinet.c | 6 +++---
net/ipv4/fib_frontend.c | 20 ++++++++++----------
net/ipv4/fib_rules.c | 2 +-
net/ipv4/fib_trie.c | 6 +++---
net/ipv4/route.c | 19 +++----------------
7 files changed, 22 insertions(+), 35 deletions(-)
diff --git a/include/net/route.h b/include/net/route.h
index 776a27f..da22243 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -108,7 +108,7 @@ extern struct ip_rt_acct __percpu *ip_rt_acct;
struct in_device;
extern int ip_rt_init(void);
-extern void rt_cache_flush(struct net *net, int how);
+extern void rt_cache_flush(struct net *net);
extern void rt_flush_dev(struct net_device *dev);
extern struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp);
extern struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 77e87af..4780045 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1225,7 +1225,7 @@ static int arp_netdev_event(struct notifier_block *this, unsigned long event,
switch (event) {
case NETDEV_CHANGEADDR:
neigh_changeaddr(&arp_tbl, dev);
- rt_cache_flush(dev_net(dev), 0);
+ rt_cache_flush(dev_net(dev));
break;
default:
break;
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index adf273f..f14eff5 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1500,7 +1500,7 @@ static int devinet_conf_proc(ctl_table *ctl, int write,
if (i == IPV4_DEVCONF_ACCEPT_LOCAL - 1 ||
i == IPV4_DEVCONF_ROUTE_LOCALNET - 1)
if ((new_value == 0) && (old_value != 0))
- rt_cache_flush(net, 0);
+ rt_cache_flush(net);
}
return ret;
@@ -1534,7 +1534,7 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
dev_disable_lro(idev->dev);
}
rtnl_unlock();
- rt_cache_flush(net, 0);
+ rt_cache_flush(net);
}
}
@@ -1551,7 +1551,7 @@ static int ipv4_doint_and_flush(ctl_table *ctl, int write,
struct net *net = ctl->extra2;
if (write && *valp != val)
- rt_cache_flush(net, 0);
+ rt_cache_flush(net);
return ret;
}
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index acdee32..8a7cd79 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -148,7 +148,7 @@ static void fib_flush(struct net *net)
}
if (flushed)
- rt_cache_flush(net, -1);
+ rt_cache_flush(net);
}
/*
@@ -999,11 +999,11 @@ static void nl_fib_lookup_exit(struct net *net)
net->ipv4.fibnl = NULL;
}
-static void fib_disable_ip(struct net_device *dev, int force, int delay)
+static void fib_disable_ip(struct net_device *dev, int force)
{
if (fib_sync_down_dev(dev, force))
fib_flush(dev_net(dev));
- rt_cache_flush(dev_net(dev), delay);
+ rt_cache_flush(dev_net(dev));
arp_ifdown(dev);
}
@@ -1020,7 +1020,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
fib_sync_up(dev);
#endif
atomic_inc(&net->ipv4.dev_addr_genid);
- rt_cache_flush(dev_net(dev), -1);
+ rt_cache_flush(dev_net(dev));
break;
case NETDEV_DOWN:
fib_del_ifaddr(ifa, NULL);
@@ -1029,9 +1029,9 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
/* Last address was deleted from this interface.
* Disable IP.
*/
- fib_disable_ip(dev, 1, 0);
+ fib_disable_ip(dev, 1);
} else {
- rt_cache_flush(dev_net(dev), -1);
+ rt_cache_flush(dev_net(dev));
}
break;
}
@@ -1045,7 +1045,7 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
struct net *net = dev_net(dev);
if (event == NETDEV_UNREGISTER) {
- fib_disable_ip(dev, 2, -1);
+ fib_disable_ip(dev, 2);
rt_flush_dev(dev);
return NOTIFY_DONE;
}
@@ -1061,14 +1061,14 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
fib_sync_up(dev);
#endif
atomic_inc(&net->ipv4.dev_addr_genid);
- rt_cache_flush(net, -1);
+ rt_cache_flush(net);
break;
case NETDEV_DOWN:
- fib_disable_ip(dev, 0, 0);
+ fib_disable_ip(dev, 0);
break;
case NETDEV_CHANGEMTU:
case NETDEV_CHANGE:
- rt_cache_flush(net, 0);
+ rt_cache_flush(net);
break;
}
return NOTIFY_DONE;
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index a83d74e..274309d 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -259,7 +259,7 @@ static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule)
static void fib4_rule_flush_cache(struct fib_rules_ops *ops)
{
- rt_cache_flush(ops->fro_net, -1);
+ rt_cache_flush(ops->fro_net);
}
static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = {
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 3c820da..8d76610 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1286,7 +1286,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
fib_release_info(fi_drop);
if (state & FA_S_ACCESSED)
- rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
+ rt_cache_flush(cfg->fc_nlinfo.nl_net);
rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE);
@@ -1333,7 +1333,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
list_add_tail_rcu(&new_fa->fa_list,
(fa ? &fa->fa_list : fa_head));
- rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
+ rt_cache_flush(cfg->fc_nlinfo.nl_net);
rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id,
&cfg->fc_nlinfo, 0);
succeeded:
@@ -1711,7 +1711,7 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
trie_leaf_remove(t, l);
if (fa->fa_state & FA_S_ACCESSED)
- rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
+ rt_cache_flush(cfg->fc_nlinfo.nl_net);
fib_release_info(fa->fa_info);
alias_free_mem_rcu(fa);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index dc9549b..ab1e7c7 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -461,11 +461,7 @@ static void rt_cache_invalidate(struct net *net)
atomic_add(shuffle + 1U, &net->ipv4.rt_genid);
}
-/*
- * delay < 0 : invalidate cache (fast : entries will be deleted later)
- * delay >= 0 : invalidate & flush cache (can be long)
- */
-void rt_cache_flush(struct net *net, int delay)
+void rt_cache_flush(struct net *net)
{
rt_cache_invalidate(net);
}
@@ -2345,7 +2341,7 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb)
void ip_rt_multicast_event(struct in_device *in_dev)
{
- rt_cache_flush(dev_net(in_dev->dev), 0);
+ rt_cache_flush(dev_net(in_dev->dev));
}
#ifdef CONFIG_SYSCTL
@@ -2354,16 +2350,7 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
size_t *lenp, loff_t *ppos)
{
if (write) {
- int flush_delay;
- ctl_table ctl;
- struct net *net;
-
- memcpy(&ctl, __ctl, sizeof(ctl));
- ctl.data = &flush_delay;
- proc_dointvec(&ctl, write, buffer, lenp, ppos);
-
- net = (struct net *)__ctl->extra1;
- rt_cache_flush(net, flush_delay);
+ rt_cache_flush((struct net *)__ctl->extra1);
return 0;
}
--
1.7.12
^ permalink raw reply related
* Re: [PATCH net-next] ipv4/route: arg delay is useless in rt_cache_flush()
From: Nicolas Dichtel @ 2012-09-07 10:41 UTC (permalink / raw)
To: Eric Dumazet; +Cc: davem, netdev
In-Reply-To: <1347013794.2484.488.camel@edumazet-glaptop>
Le 07/09/2012 12:29, Eric Dumazet a écrit :
> On Fri, 2012-09-07 at 11:31 +0200, Nicolas Dichtel wrote:
>> Since route cache deletion (89aef8921bfbac22f), delay is no
>> more used. Remove it.
>>
> ...
>
>> #ifdef CONFIG_SYSCTL
>> @@ -2354,16 +2350,12 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
>> size_t *lenp, loff_t *ppos)
>> {
>> if (write) {
>> - int flush_delay;
>> ctl_table ctl;
>> struct net *net;
>>
>> memcpy(&ctl, __ctl, sizeof(ctl));
>> - ctl.data = &flush_delay;
>> - proc_dointvec(&ctl, write, buffer, lenp, ppos);
>> -
>> net = (struct net *)__ctl->extra1;
>> - rt_cache_flush(net, flush_delay);
>> + rt_cache_flush(net);
>> return 0;
>> }
>>
>
> Why do you keep ctl then ?
>
> if (write) {
> rt_cache_flush((struct net *)__ctl->extra1);
> return 0;
> }
>
>
Right, there is no reason.
Regards,
Nicolas
^ permalink raw reply
* Re: [PATCH net-next] ipv4/route: arg delay is useless in rt_cache_flush()
From: Eric Dumazet @ 2012-09-07 10:29 UTC (permalink / raw)
To: Nicolas Dichtel; +Cc: davem, netdev
In-Reply-To: <1347010284-3419-1-git-send-email-nicolas.dichtel@6wind.com>
On Fri, 2012-09-07 at 11:31 +0200, Nicolas Dichtel wrote:
> Since route cache deletion (89aef8921bfbac22f), delay is no
> more used. Remove it.
>
...
> #ifdef CONFIG_SYSCTL
> @@ -2354,16 +2350,12 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
> size_t *lenp, loff_t *ppos)
> {
> if (write) {
> - int flush_delay;
> ctl_table ctl;
> struct net *net;
>
> memcpy(&ctl, __ctl, sizeof(ctl));
> - ctl.data = &flush_delay;
> - proc_dointvec(&ctl, write, buffer, lenp, ppos);
> -
> net = (struct net *)__ctl->extra1;
> - rt_cache_flush(net, flush_delay);
> + rt_cache_flush(net);
> return 0;
> }
>
Why do you keep ctl then ?
if (write) {
rt_cache_flush((struct net *)__ctl->extra1);
return 0;
}
^ permalink raw reply
* [PATCH net-next] ipv4/route: arg delay is useless in rt_cache_flush()
From: Nicolas Dichtel @ 2012-09-07 9:31 UTC (permalink / raw)
To: davem; +Cc: netdev, Nicolas Dichtel
Since route cache deletion (89aef8921bfbac22f), delay is no
more used. Remove it.
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
include/net/route.h | 2 +-
net/ipv4/arp.c | 2 +-
net/ipv4/devinet.c | 6 +++---
net/ipv4/fib_frontend.c | 20 ++++++++++----------
net/ipv4/fib_rules.c | 2 +-
net/ipv4/fib_trie.c | 6 +++---
net/ipv4/route.c | 14 +++-----------
7 files changed, 22 insertions(+), 30 deletions(-)
diff --git a/include/net/route.h b/include/net/route.h
index 776a27f..da22243 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -108,7 +108,7 @@ extern struct ip_rt_acct __percpu *ip_rt_acct;
struct in_device;
extern int ip_rt_init(void);
-extern void rt_cache_flush(struct net *net, int how);
+extern void rt_cache_flush(struct net *net);
extern void rt_flush_dev(struct net_device *dev);
extern struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp);
extern struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 77e87af..4780045 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1225,7 +1225,7 @@ static int arp_netdev_event(struct notifier_block *this, unsigned long event,
switch (event) {
case NETDEV_CHANGEADDR:
neigh_changeaddr(&arp_tbl, dev);
- rt_cache_flush(dev_net(dev), 0);
+ rt_cache_flush(dev_net(dev));
break;
default:
break;
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index adf273f..f14eff5 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1500,7 +1500,7 @@ static int devinet_conf_proc(ctl_table *ctl, int write,
if (i == IPV4_DEVCONF_ACCEPT_LOCAL - 1 ||
i == IPV4_DEVCONF_ROUTE_LOCALNET - 1)
if ((new_value == 0) && (old_value != 0))
- rt_cache_flush(net, 0);
+ rt_cache_flush(net);
}
return ret;
@@ -1534,7 +1534,7 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
dev_disable_lro(idev->dev);
}
rtnl_unlock();
- rt_cache_flush(net, 0);
+ rt_cache_flush(net);
}
}
@@ -1551,7 +1551,7 @@ static int ipv4_doint_and_flush(ctl_table *ctl, int write,
struct net *net = ctl->extra2;
if (write && *valp != val)
- rt_cache_flush(net, 0);
+ rt_cache_flush(net);
return ret;
}
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index acdee32..8a7cd79 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -148,7 +148,7 @@ static void fib_flush(struct net *net)
}
if (flushed)
- rt_cache_flush(net, -1);
+ rt_cache_flush(net);
}
/*
@@ -999,11 +999,11 @@ static void nl_fib_lookup_exit(struct net *net)
net->ipv4.fibnl = NULL;
}
-static void fib_disable_ip(struct net_device *dev, int force, int delay)
+static void fib_disable_ip(struct net_device *dev, int force)
{
if (fib_sync_down_dev(dev, force))
fib_flush(dev_net(dev));
- rt_cache_flush(dev_net(dev), delay);
+ rt_cache_flush(dev_net(dev));
arp_ifdown(dev);
}
@@ -1020,7 +1020,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
fib_sync_up(dev);
#endif
atomic_inc(&net->ipv4.dev_addr_genid);
- rt_cache_flush(dev_net(dev), -1);
+ rt_cache_flush(dev_net(dev));
break;
case NETDEV_DOWN:
fib_del_ifaddr(ifa, NULL);
@@ -1029,9 +1029,9 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
/* Last address was deleted from this interface.
* Disable IP.
*/
- fib_disable_ip(dev, 1, 0);
+ fib_disable_ip(dev, 1);
} else {
- rt_cache_flush(dev_net(dev), -1);
+ rt_cache_flush(dev_net(dev));
}
break;
}
@@ -1045,7 +1045,7 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
struct net *net = dev_net(dev);
if (event == NETDEV_UNREGISTER) {
- fib_disable_ip(dev, 2, -1);
+ fib_disable_ip(dev, 2);
rt_flush_dev(dev);
return NOTIFY_DONE;
}
@@ -1061,14 +1061,14 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
fib_sync_up(dev);
#endif
atomic_inc(&net->ipv4.dev_addr_genid);
- rt_cache_flush(net, -1);
+ rt_cache_flush(net);
break;
case NETDEV_DOWN:
- fib_disable_ip(dev, 0, 0);
+ fib_disable_ip(dev, 0);
break;
case NETDEV_CHANGEMTU:
case NETDEV_CHANGE:
- rt_cache_flush(net, 0);
+ rt_cache_flush(net);
break;
}
return NOTIFY_DONE;
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index a83d74e..274309d 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -259,7 +259,7 @@ static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule)
static void fib4_rule_flush_cache(struct fib_rules_ops *ops)
{
- rt_cache_flush(ops->fro_net, -1);
+ rt_cache_flush(ops->fro_net);
}
static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = {
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 3c820da..8d76610 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1286,7 +1286,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
fib_release_info(fi_drop);
if (state & FA_S_ACCESSED)
- rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
+ rt_cache_flush(cfg->fc_nlinfo.nl_net);
rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE);
@@ -1333,7 +1333,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
list_add_tail_rcu(&new_fa->fa_list,
(fa ? &fa->fa_list : fa_head));
- rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
+ rt_cache_flush(cfg->fc_nlinfo.nl_net);
rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id,
&cfg->fc_nlinfo, 0);
succeeded:
@@ -1711,7 +1711,7 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
trie_leaf_remove(t, l);
if (fa->fa_state & FA_S_ACCESSED)
- rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
+ rt_cache_flush(cfg->fc_nlinfo.nl_net);
fib_release_info(fa->fa_info);
alias_free_mem_rcu(fa);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index dc9549b..915c592 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -461,11 +461,7 @@ static void rt_cache_invalidate(struct net *net)
atomic_add(shuffle + 1U, &net->ipv4.rt_genid);
}
-/*
- * delay < 0 : invalidate cache (fast : entries will be deleted later)
- * delay >= 0 : invalidate & flush cache (can be long)
- */
-void rt_cache_flush(struct net *net, int delay)
+void rt_cache_flush(struct net *net)
{
rt_cache_invalidate(net);
}
@@ -2345,7 +2341,7 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb)
void ip_rt_multicast_event(struct in_device *in_dev)
{
- rt_cache_flush(dev_net(in_dev->dev), 0);
+ rt_cache_flush(dev_net(in_dev->dev));
}
#ifdef CONFIG_SYSCTL
@@ -2354,16 +2350,12 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
size_t *lenp, loff_t *ppos)
{
if (write) {
- int flush_delay;
ctl_table ctl;
struct net *net;
memcpy(&ctl, __ctl, sizeof(ctl));
- ctl.data = &flush_delay;
- proc_dointvec(&ctl, write, buffer, lenp, ppos);
-
net = (struct net *)__ctl->extra1;
- rt_cache_flush(net, flush_delay);
+ rt_cache_flush(net);
return 0;
}
--
1.7.12
^ permalink raw reply related
* Re: MBIM
From: Bjørn Mork @ 2012-09-07 8:53 UTC (permalink / raw)
To: Oliver Neukum; +Cc: alexey.orishko, netdev, linux-usb
In-Reply-To: <3121990.L41g6gGrVV@linux-lqwf.site>
Oliver Neukum <oneukum@suse.de> writes:
> On Thursday 06 September 2012 10:17:46 Bjørn Mork wrote:
>> Not really related, but I am still worrying how MBIM is going to fit
>> into the usbnet model where you have a strict relation between one
>> netdev and one USB interface. Do you see any way usbnet could be
>> extended to manage a list of netdevs?
>>
>> All the netdev related functions doing
>>
>> struct usbnet *dev = netdev_priv(net);
>>
>> would still work. But all the USB related functions using dev->net to
>> get the netdev would fail. Maybe this will be too difficult to
>> implement within the usbnet framework at all?
>
> It depends on how much support we get from upper layers.
> You can give two IPs to an ethernet card as well.
Yes, of course. But I don't think that fits the MBIM model, where
multiple independent connections (Internet, VoIP, MMS, VPN1, VPN2, etc)
to different APNs will be multiplexed over the same USB endpoints. And
to make this not fly at all: Some of these may be IPv4, some IPv6 and
some dual stack. You cannot support that on a single netdev. Mixing
them all together on the host will not do. When the driver sees an IPv6
multicast packet (RS, ND, whatever) on the netdev, which MBIM session
should it forward that packet too?
If I understand MBIM correctly, we will see device configurations with
_one_ CDC data interface carrying all data traffic for multiple device
functions. A MBIM driver must de-multiplex this, and each IP function
should be routed to its own netdev IMHO.
> It would be best if you could come up with some preliminary code
> at least.
Yup. Finally got a device. Will start playing.
Bjørn
^ permalink raw reply
* MBIM (was: Re: changing usbnet's API to better deal with cdc-ncm)
From: Oliver Neukum @ 2012-09-07 7:40 UTC (permalink / raw)
To: Bjørn Mork
Cc: alexey.orishko-0IS4wlFg1OjSUeElwK9/Pw,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <87ehmf36qd.fsf-lbf33ChDnrE/G1V5fR+Y7Q@public.gmane.org>
On Thursday 06 September 2012 10:17:46 Bjørn Mork wrote:
> Not really related, but I am still worrying how MBIM is going to fit
> into the usbnet model where you have a strict relation between one
> netdev and one USB interface. Do you see any way usbnet could be
> extended to manage a list of netdevs?
>
> All the netdev related functions doing
>
> struct usbnet *dev = netdev_priv(net);
>
> would still work. But all the USB related functions using dev->net to
> get the netdev would fail. Maybe this will be too difficult to
> implement within the usbnet framework at all?
It depends on how much support we get from upper layers.
You can give two IPs to an ethernet card as well.
It would be best if you could come up with some preliminary code
at least.
Reagrds
Oliver
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" 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
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