* RE: 3.1.0 rtl8169_open oops.
From: hayeswang @ 2011-11-17 12:26 UTC (permalink / raw)
To: 'Dave Jones', 'Francois Romieu'
Cc: netdev, kernel-team, dwmw2
In-Reply-To: <20111117005355.GA8466@redhat.com>
> -----Original Message-----
> From: Dave Jones [mailto:davej@redhat.com]
> Sent: Thursday, November 17, 2011 8:54 AM
> To: Francois Romieu
> Cc: netdev@vger.kernel.org; kernel-team@fedoraproject.org;
> Hayeswang; dwmw2@infradead.org
> Subject: Re: 3.1.0 rtl8169_open oops.
>
> On Thu, Nov 17, 2011 at 01:34:36AM +0100, Francois Romieu wrote:
> > Dave Jones <davej@redhat.com> :
> > [...]
> > > (gdb) list *(rtl8169_open)+0x34e
> > > 0x4c0f is in rtl8169_open (drivers/net/r8169.c:1881).
> > > 1876 bool rc = false;
> > > 1877
> > > 1878 if (fw->size < FW_OPCODE_SIZE)
> > > 1879 goto out;
> > > 1880
> > > 1881 if (!fw_info->magic) {
> > > 1882 size_t i, size, start;
> > > 1883 u8 checksum = 0;
> > > 1884
> > > 1885 if (fw->size < sizeof(*fw_info))
> >
My colleague tries Fedora 16 and it works fine with several different chips. We
couldn't reproduce the issue.
> > Give me 24h. I hope it is not as trivial as it seems :o(
> >
> > Btw the firmware included in F16 is not up-to-date (see
> > http://marc.info/?l=linux-kernel&m=131295492507686&w=2).
> The driver should
> > not mind though.
>
> That reminds me. Since the kernel.org compromise, where does
> linux-firmware live now ?
>
I submitted the new firmwares to
http://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git
However, the owner doesn't update them yet. You could reference
http://www.spinics.net/lists/netdev/msg178015.html
Best Regards,
Hayes
^ permalink raw reply
* RE: [linux-firmware v6 2/4] rtl_nic: add new firmware for RTL8111F
From: hayeswang @ 2011-11-17 12:16 UTC (permalink / raw)
To: dwmw2, ben; +Cc: romieu, netdev
In-Reply-To: <1319634425-1529-2-git-send-email-hayeswang@realtek.com>
> -----Original Message-----
> From: Hayeswang [mailto:hayeswang@realtek.com]
> Sent: Wednesday, October 26, 2011 9:07 PM
> To: dwmw2@infradead.org; ben@decadent.org.uk
> Cc: romieu@fr.zoreil.com; netdev@vger.kernel.org; Hayeswang
> Subject: [linux-firmware v6 2/4] rtl_nic: add new firmware
> for RTL8111F
>
> Add new firmware:
> 1. rtl_nic/rtl8168f-1.fw
> version: 0.0.3
> 2. rtl_nic/rtl8168f-2.fw
> version: 0.0.3
>
> Signed-off-by: Hayes Wang <hayeswang@realtek.com>
> ---
> WHENCE | 6 ++++++
> rtl_nic/rtl8168f-1.fw | Bin 0 -> 3136 bytes
> rtl_nic/rtl8168f-2.fw | Bin 0 -> 992 bytes
> 3 files changed, 6 insertions(+), 0 deletions(-)
> create mode 100644 rtl_nic/rtl8168f-1.fw
> create mode 100644 rtl_nic/rtl8168f-2.fw
>
Hi sirs,
Excuse me. Someone asks me these firmwares. Are these pending? Any response?
Best Regards,
Hayes
^ permalink raw reply
* Re: [PATCH 1/2] net: add network priority cgroup infrastructure
From: Neil Horman @ 2011-11-17 11:56 UTC (permalink / raw)
To: John Fastabend; +Cc: netdev@vger.kernel.org, Love, Robert W, David S. Miller
In-Reply-To: <4EC4EF46.7010009@intel.com>
On Thu, Nov 17, 2011 at 03:25:58AM -0800, John Fastabend wrote:
> On 11/16/2011 12:51 PM, Neil Horman wrote:
> > This patch adds in the infrastructure code to create the network priority
> > cgroup. The cgroup, in addition to the standard processes file creates two
> > control files:
> >
> > 1) prioidx - This is a read-only file that exports the index of this cgroup.
> > This is a value that is both arbitrary and unique to a cgroup in this subsystem,
> > and is used to index the per-device priority map
> >
> > 2) priomap - This is a writeable file. On read it reports a table of 2-tuples
> > <name:priority> where name is the name of a network interface and priority is
> > indicates the priority assigned to frames egresessing on the named interface and
> > originating from a pid in this cgroup
> >
> > This cgroup allows for skb priority to be set prior to a root qdisc getting
> > selected. This is benenficial for DCB enabled systems, in that it allows for any
> > application to use dcb configured priorities so without application modification
> >
> > Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> > Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> > CC: Robert Love <robert.w.love@intel.com>
> > CC: "David S. Miller" <davem@davemloft.net>
> > ---
> > include/linux/cgroup_subsys.h | 8 +
> > include/linux/netdevice.h | 4 +
> > include/net/netprio_cgroup.h | 66 ++++++++
> > include/net/sock.h | 3 +
> > net/Kconfig | 7 +
> > net/core/Makefile | 1 +
> > net/core/dev.c | 13 ++
> > net/core/netprio_cgroup.c | 340 +++++++++++++++++++++++++++++++++++++++++
> > net/core/sock.c | 22 +++-
> > net/socket.c | 2 +
> > 10 files changed, 465 insertions(+), 1 deletions(-)
> > create mode 100644 include/net/netprio_cgroup.h
> > create mode 100644 net/core/netprio_cgroup.c
> >
>
> Hi Neil,
>
> couple more comments.
>
Thanks John, I'll fix these points up and post a v2 later today.
Neil
>
^ permalink raw reply
* Re: [PATCH 1/2] net: add network priority cgroup infrastructure
From: John Fastabend @ 2011-11-17 11:25 UTC (permalink / raw)
To: Neil Horman; +Cc: netdev@vger.kernel.org, Love, Robert W, David S. Miller
In-Reply-To: <1321476666-8225-2-git-send-email-nhorman@tuxdriver.com>
On 11/16/2011 12:51 PM, Neil Horman wrote:
> This patch adds in the infrastructure code to create the network priority
> cgroup. The cgroup, in addition to the standard processes file creates two
> control files:
>
> 1) prioidx - This is a read-only file that exports the index of this cgroup.
> This is a value that is both arbitrary and unique to a cgroup in this subsystem,
> and is used to index the per-device priority map
>
> 2) priomap - This is a writeable file. On read it reports a table of 2-tuples
> <name:priority> where name is the name of a network interface and priority is
> indicates the priority assigned to frames egresessing on the named interface and
> originating from a pid in this cgroup
>
> This cgroup allows for skb priority to be set prior to a root qdisc getting
> selected. This is benenficial for DCB enabled systems, in that it allows for any
> application to use dcb configured priorities so without application modification
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> CC: Robert Love <robert.w.love@intel.com>
> CC: "David S. Miller" <davem@davemloft.net>
> ---
> include/linux/cgroup_subsys.h | 8 +
> include/linux/netdevice.h | 4 +
> include/net/netprio_cgroup.h | 66 ++++++++
> include/net/sock.h | 3 +
> net/Kconfig | 7 +
> net/core/Makefile | 1 +
> net/core/dev.c | 13 ++
> net/core/netprio_cgroup.c | 340 +++++++++++++++++++++++++++++++++++++++++
> net/core/sock.c | 22 +++-
> net/socket.c | 2 +
> 10 files changed, 465 insertions(+), 1 deletions(-)
> create mode 100644 include/net/netprio_cgroup.h
> create mode 100644 net/core/netprio_cgroup.c
>
Hi Neil,
couple more comments.
> diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
> index ac663c1..0bd390c 100644
> --- a/include/linux/cgroup_subsys.h
> +++ b/include/linux/cgroup_subsys.h
> @@ -59,8 +59,16 @@ SUBSYS(net_cls)
> SUBSYS(blkio)
> #endif
>
> +/* */
> +
> #ifdef CONFIG_CGROUP_PERF
> SUBSYS(perf)
> #endif
>
> /* */
> +
> +#ifdef CONFIG_NETPRIO_CGROUP
> +SUBSYS(net_prio)
> +#endif
> +
> +/* */
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 0db1f5f..86e8c3f 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -50,6 +50,7 @@
> #ifdef CONFIG_DCB
> #include <net/dcbnl.h>
> #endif
> +#include <net/netprio_cgroup.h>
>
> struct vlan_group;
> struct netpoll_info;
> @@ -1312,6 +1313,9 @@ struct net_device {
> /* max exchange id for FCoE LRO by ddp */
> unsigned int fcoe_ddp_xid;
> #endif
> +#if IS_ENABLED(CONFIG_NETPRIO_CGROUP)
> + struct netprio_map *priomap;
> +#endif
Any reason not to annotate this? 'struct netprio_map __rcu *priomap;' and
then use rcu_dereference_protected() throughout.
> /* phy device may attach itself for hardware timestamping */
> struct phy_device *phydev;
>
> diff --git a/include/net/netprio_cgroup.h b/include/net/netprio_cgroup.h
> new file mode 100644
> index 0000000..6b65936
> --- /dev/null
> +++ b/include/net/netprio_cgroup.h
> @@ -0,0 +1,66 @@
> +/*
> + * netprio_cgroup.h Control Group Priority set
> + *
> + *
> + * Authors: Neil Horman <nhorman@tuxdriver.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the Free
> + * Software Foundation; either version 2 of the License, or (at your option)
> + * any later version.
> + *
> + */
> +
> +#ifndef _NETPRIO_CGROUP_H
> +#define _NETPRIO_CGROUP_H
> +#include <linux/module.h>
> +#include <linux/cgroup.h>
> +#include <linux/hardirq.h>
> +#include <linux/rcupdate.h>
> +
> +struct cgroup_netprio_state
> +{
> + struct cgroup_subsys_state css;
> + u32 prioidx;
> +};
> +
> +struct netprio_map {
> + struct rcu_head rcu;
> + u32 priomap_len;
> + u32 priomap[];
> +};
> +
> +#ifdef CONFIG_CGROUPS
> +
> +#ifndef CONFIG_NETPRIO_CGROUP
> +extern int net_prio_subsys_id;
> +#endif
> +
> +extern void sock_update_netprioidx(struct sock *sk);
> +extern void skb_update_prio(struct sk_buff *skb);
> +
> +static inline struct cgroup_netprio_state
> + *task_netprio_state(struct task_struct *p)
> +{
> +#if IS_ENABLED(CONFIG_NETPRIO_CGROUP)
> + return container_of(task_subsys_state(p, net_prio_subsys_id),
> + struct cgroup_netprio_state, css);
> +#else
> + return NULL;
> +#endif
> +}
> +
> +#else
> +
> +#define sock_update_netprioidx(sk)
> +#define skb_update_prio(skb)
> +
> +static inline struct cgroup_netprio_state
> + *task_netprio_state(struct task_struct *p)
> +{
> + return NULL;
> +}
> +
> +#endif
> +
> +#endif /* _NET_CLS_CGROUP_H */
> diff --git a/include/net/sock.h b/include/net/sock.h
> index 5ac682f..87b24aa 100644
> --- a/include/net/sock.h
> +++ b/include/net/sock.h
> @@ -321,6 +321,9 @@ struct sock {
> unsigned short sk_ack_backlog;
> unsigned short sk_max_ack_backlog;
> __u32 sk_priority;
> +#ifdef CONFIG_CGROUPS
> + __u32 sk_cgrp_prioidx;
> +#endif
> struct pid *sk_peer_pid;
> const struct cred *sk_peer_cred;
> long sk_rcvtimeo;
> diff --git a/net/Kconfig b/net/Kconfig
> index a073148..63d2c5d 100644
> --- a/net/Kconfig
> +++ b/net/Kconfig
> @@ -232,6 +232,13 @@ config XPS
> depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS
> default y
>
> +config NETPRIO_CGROUP
> + tristate "Network priority cgroup"
> + depends on CGROUPS
> + ---help---
> + Cgroup subsystem for use in assigning processes to network priorities on
> + a per-interface basis
> +
> config HAVE_BPF_JIT
> bool
>
> diff --git a/net/core/Makefile b/net/core/Makefile
> index 0d357b1..3606d40 100644
> --- a/net/core/Makefile
> +++ b/net/core/Makefile
> @@ -19,3 +19,4 @@ obj-$(CONFIG_FIB_RULES) += fib_rules.o
> obj-$(CONFIG_TRACEPOINTS) += net-traces.o
> obj-$(CONFIG_NET_DROP_MONITOR) += drop_monitor.o
> obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += timestamping.o
> +obj-$(CONFIG_NETPRIO_CGROUP) += netprio_cgroup.o
> diff --git a/net/core/dev.c b/net/core/dev.c
> index b7ba81a..a1dca83 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -2456,6 +2456,17 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
> return rc;
> }
>
> +#ifdef CONFIG_CGROUPS
> +void skb_update_prio(struct sk_buff *skb)
> +{
> + struct netprio_map *map = rcu_dereference(skb->dev->priomap);
> +
> + if ((!skb->priority) && (skb->sk) && map)
> + skb->priority = map->priomap[skb->sk->sk_cgrp_prioidx];
> +}
> +EXPORT_SYMBOL_GPL(skb_update_prio);
> +#endif
> +
> static DEFINE_PER_CPU(int, xmit_recursion);
> #define RECURSION_LIMIT 10
>
> @@ -2496,6 +2507,8 @@ int dev_queue_xmit(struct sk_buff *skb)
> */
> rcu_read_lock_bh();
>
> + skb_update_prio(skb);
> +
> txq = dev_pick_tx(dev, skb);
> q = rcu_dereference_bh(txq->qdisc);
>
> diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
> new file mode 100644
> index 0000000..14e896c
> --- /dev/null
> +++ b/net/core/netprio_cgroup.c
> @@ -0,0 +1,340 @@
> +/*
> + * net/sched/cls_cgroup.c Control Group Classifier
^^^^^^^^^^^^^^^^^^
should be netprio_cgroup.c presumably.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + *
> + * Authors: Thomas Graf <tgraf@suug.ch>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
> +#include <linux/string.h>
> +#include <linux/errno.h>
> +#include <linux/skbuff.h>
> +#include <linux/cgroup.h>
> +#include <linux/rcupdate.h>
> +#include <linux/atomic.h>
> +#include <net/rtnetlink.h>
> +#include <net/pkt_cls.h>
> +#include <net/sock.h>
> +#include <net/netprio_cgroup.h>
> +
> +static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss,
> + struct cgroup *cgrp);
> +static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp);
> +static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp);
> +
> +struct cgroup_subsys net_prio_subsys = {
> + .name = "net_prio",
> + .create = cgrp_create,
> + .destroy = cgrp_destroy,
> + .populate = cgrp_populate,
> +#ifdef CONFIG_NETPRIO_CGROUP
> + .subsys_id = net_prio_subsys_id,
> +#endif
> + .module = THIS_MODULE
> +};
> +
> +#define PRIOIDX_SZ 128
> +
> +static unsigned long prioidx_map[PRIOIDX_SZ];
> +static DEFINE_SPINLOCK(prioidx_map_lock);
> +static atomic_t max_prioidx = ATOMIC_INIT(0);
> +
> +static inline struct cgroup_netprio_state *cgrp_netprio_state(struct cgroup *cgrp)
> +{
> + return container_of(cgroup_subsys_state(cgrp, net_prio_subsys_id),
> + struct cgroup_netprio_state, css);
> +}
> +
> +static int get_prioidx(u32 *prio)
> +{
> + unsigned long flags;
> + u32 prioidx;
> +
> + spin_lock_irqsave(&prioidx_map_lock, flags);
> + prioidx = find_first_zero_bit(prioidx_map, sizeof(unsigned long) * PRIOIDX_SZ);
> + set_bit(prioidx, prioidx_map);
> + spin_unlock_irqrestore(&prioidx_map_lock, flags);
> + if (prioidx == sizeof(unsigned long) * PRIOIDX_SZ)
> + return -ENOSPC;
> +
> + atomic_set(&max_prioidx, prioidx);
> + *prio = prioidx;
> + return 0;
> +}
> +
> +static void put_prioidx(u32 idx)
> +{
> + unsigned long flags;
> + spin_lock_irqsave(&prioidx_map_lock, flags);
> + clear_bit(idx, prioidx_map);
> + spin_unlock_irqrestore(&prioidx_map_lock, flags);
> +}
> +
> +static void extend_netdev_table(struct net_device *dev, u32 new_len)
> +{
> + size_t new_size = sizeof(struct netprio_map) +
> + ((sizeof(u32) * new_len));
> + struct netprio_map *new_priomap = kzalloc(new_size, GFP_KERNEL);
> + struct netprio_map *old_priomap;
> + int i;
> +
> + old_priomap = rcu_dereference_protected(dev->priomap, 1);
This always has rtnl_lock hence the '1' so use rtnl_dereference().
> +
also extra white line.
> +
> + if (!new_priomap) {
> + printk(KERN_WARNING "Unable to alloc new priomap!\n");
> + return;
> + }
> +
> + for (i = 0;
> + dev->priomap && (i < dev->priomap->priomap_len);
^^^^^^^^^^^^ ^^^^^^^^^^^^^
probably should use old_priomap here.
> + i++)
> + new_priomap->priomap[i] = dev->priomap->priomap[i];
> +
> + new_priomap->priomap_len = new_len;
> +
> + rcu_assign_pointer(dev->priomap, new_priomap);
> + if (old_priomap)
> + kfree_rcu(old_priomap, rcu);
> +
remove extra line.
> +}
> +
> +static void update_netdev_tables(void)
> +{
> + struct net_device *dev;
> + u32 max_len = atomic_read(&max_prioidx);
> +
> + rtnl_lock();
> +
> + for_each_netdev(&init_net, dev) {
> + if ((!dev->priomap) ||
> + (dev->priomap->priomap_len < max_len))
> + extend_netdev_table(dev, max_len);
With __rcu change add rtnl_dereference()
> + }
> +
> + rtnl_unlock();
> +}
> +
> +static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss,
> + struct cgroup *cgrp)
> +{
> + struct cgroup_netprio_state *cs;
> + int ret;
> +
> + cs = kzalloc(sizeof(*cs), GFP_KERNEL);
> + if (!cs)
> + return ERR_PTR(-ENOMEM);
> +
> + if (cgrp->parent && cgrp_netprio_state(cgrp->parent)->prioidx)
> + return ERR_PTR(-EINVAL);
> +
> + ret = get_prioidx(&cs->prioidx);
> + if (ret != 0) {
> + printk(KERN_WARNING "No space in priority index array\n");
> + return ERR_PTR(ret);
> + }
> +
> + return &cs->css;
> +}
> +
> +static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp)
> +{
> + struct cgroup_netprio_state *cs;
> + struct net_device *dev;
> +
> + cs = cgrp_netprio_state(cgrp);
> + rtnl_lock();
> + for_each_netdev(&init_net, dev) {
> + if (dev->priomap)
ditto rtnl_dereference()
> + dev->priomap->priomap[cs->prioidx] = 0;
> + }
> + rtnl_unlock();
> + put_prioidx(cs->prioidx);
> +out_free:
> + kfree(cs);
> +}
> +
> +static u64 read_prioidx(struct cgroup *cgrp, struct cftype *cft)
> +{
> + return (u64)cgrp_netprio_state(cgrp)->prioidx;
> +}
> +
> +static int read_priomap(struct cgroup *cont, struct cftype *cft,
> + struct cgroup_map_cb *cb)
> +{
> + struct net_device *dev;
> + u32 prioidx = cgrp_netprio_state(cont)->prioidx;
> + u32 priority;
> +
> + /*
> + * Stub until I add the per-interface priority map
> + */
we have a per interface map now... so drop the comments.
> + rcu_read_lock();
> + for_each_netdev_rcu(&init_net, dev) {
> + priority = dev->priomap ? dev->priomap->priomap[prioidx] : 0;
This really needs a rcu_dereference() AFAICT.
> + cb->fill(cb, dev->name, priority);
> + }
> + rcu_read_unlock();
> + return 0;
> +}
> +
> +static int write_priomap(struct cgroup *cgrp, struct cftype *cft,
> + const char *buffer)
> +{
> + char *devname = kstrdup(buffer, GFP_KERNEL);
> + int ret = -EINVAL;
> + u32 prioidx = cgrp_netprio_state(cgrp)->prioidx;
> + unsigned long priority;
> + char *priostr;
> + struct net_device *dev;
> +
> + devname = kstrdup(buffer, GFP_KERNEL);
> + if (!devname)
> + return -ENOMEM;
> +
> + /*
> + * Minimally sized valid priomap string
> + */
> + if (strlen(devname) < 3)
> + goto out_free_devname;
> +
> + priostr = strstr(devname, " ");
> + if (!priostr)
> + goto out_free_devname;
> +
> + /*
> + *Separate the devname from the associated priority
> + *and advance the priostr poitner to the priority value
> + */
> + *priostr = '\0';
> + priostr++;
> +
> + /*
> + * If the priostr points to NULL, we're at the end of the passed
> + * in string, and its not a valid write
> + */
> + if (*priostr == '\0')
> + goto out_free_devname;
> +
> + ret = kstrtoul(priostr, 10, &priority);
> + if (ret < 0)
> + goto out_free_devname;
> +
> + ret = -ENODEV;
> +
> + dev = dev_get_by_name(&init_net, devname);
> + if (!dev)
> + goto out_free_devname;
> +
> + update_netdev_tables();
> + ret = 0;
> + if (dev->priomap)
> + dev->priomap->priomap[prioidx] = priority;
> +
Whats protecting this? This needs a dereference and rcu_read_lock() I think.
> + dev_put(dev);
> +
> +out_free_devname:
> + kfree(devname);
> + return ret;
> +}
> +
> +static struct cftype ss_files[] = {
> + {
> + .name = "prioidx",
> + .read_u64 = read_prioidx,
> + },
> + {
> + .name = "ifpriomap",
> + .read_map = read_priomap,
> + .write_string = write_priomap,
> + },
> +};
> +
> +static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp)
> +{
> + return cgroup_add_files(cgrp, ss, ss_files, ARRAY_SIZE(ss_files));
> +}
> +
> +static int netprio_device_event(struct notifier_block *unused,
> + unsigned long event, void *ptr)
> +{
> + struct net_device *dev = ptr;
> + struct netprio_map *old;
> + u32 max_len = atomic_read(&max_prioidx);
> +
> + old = rcu_dereference_protected(dev->priomap, 1);
> + /*
> + * Note this is called with rtnl_lock held so we have update side
> + * protection on our rcu assignments
> + */
> +
> + switch (event) {
> +
> + case NETDEV_REGISTER:
> + if (max_len)
> + extend_netdev_table(dev, max_len);
> + break;
> + case NETDEV_UNREGISTER:
> + rcu_assign_pointer(dev->priomap, NULL);
> + if (old)
> + kfree_rcu(old, rcu);
> + break;
> + }
> + return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block netprio_device_notifier = {
> + .notifier_call = netprio_device_event
> +};
> +
> +static int __init init_cgroup_netprio(void)
> +{
> + int ret;
> +
> + ret = cgroup_load_subsys(&net_prio_subsys);
> + if (ret)
> + goto out;
> +#ifndef CONFIG_NETPRIO_CGROUP
> + smp_wmb();
> + net_prio_subsys_id = net_prio_subsys.subsys_id;
> +#endif
> +
> + register_netdevice_notifier(&netprio_device_notifier);
> +
> +out:
> + return ret;
> +}
> +
> +static void __exit exit_cgroup_netprio(void)
> +{
> + struct netprio_map *old;
> + struct net_device *dev;
> +
> + unregister_netdevice_notifier(&netprio_device_notifier);
> +
> + cgroup_unload_subsys(&net_prio_subsys);
> +
> +#ifndef CONFIG_NETPRIO_CGROUP
> + net_prio_subsys_id = -1;
> + synchronize_rcu();
> +#endif
> +
> + rtnl_lock();
> + for_each_netdev(&init_net, dev) {
> + old = dev->priomap;
rtnl_dereference() here also if adding __rcu
> + rcu_assign_pointer(dev->priomap, NULL);
> + if (old)
> + kfree_rcu(old, rcu);
> + }
> + rtnl_unlock();
> +}
> +
> +module_init(init_cgroup_netprio);
> +module_exit(exit_cgroup_netprio);
> +MODULE_LICENSE("GPL v2");
> diff --git a/net/core/sock.c b/net/core/sock.c
> index 5a08762..77a4888 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -125,6 +125,7 @@
> #include <net/xfrm.h>
> #include <linux/ipsec.h>
> #include <net/cls_cgroup.h>
> +#include <net/netprio_cgroup.h>
>
> #include <linux/filter.h>
>
> @@ -221,10 +222,16 @@ __u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX;
> int sysctl_optmem_max __read_mostly = sizeof(unsigned long)*(2*UIO_MAXIOV+512);
> EXPORT_SYMBOL(sysctl_optmem_max);
>
> -#if defined(CONFIG_CGROUPS) && !defined(CONFIG_NET_CLS_CGROUP)
> +#if defined(CONFIG_CGROUPS)
> +#if !defined(CONFIG_NET_CLS_CGROUP)
> int net_cls_subsys_id = -1;
> EXPORT_SYMBOL_GPL(net_cls_subsys_id);
> #endif
> +#if !defined(CONFIG_NETPRIO_CGROUP)
> +int net_prio_subsys_id = -1;
> +EXPORT_SYMBOL_GPL(net_prio_subsys_id);
> +#endif
> +#endif
>
> static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
> {
> @@ -1111,6 +1118,18 @@ void sock_update_classid(struct sock *sk)
> sk->sk_classid = classid;
> }
> EXPORT_SYMBOL(sock_update_classid);
> +
> +void sock_update_netprioidx(struct sock *sk)
> +{
> + struct cgroup_netprio_state *state;
> + if (in_interrupt())
> + return;
> + rcu_read_lock();
> + state = task_netprio_state(current);
> + sk->sk_cgrp_prioidx = state ? state->prioidx : 0;
> + rcu_read_unlock();
> +}
> +EXPORT_SYMBOL_GPL(sock_update_netprioidx);
> #endif
>
> /**
> @@ -1138,6 +1157,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
> atomic_set(&sk->sk_wmem_alloc, 1);
>
> sock_update_classid(sk);
> + sock_update_netprioidx(sk);
> }
>
> return sk;
> diff --git a/net/socket.c b/net/socket.c
> index 2877647..108716f 100644
> --- a/net/socket.c
> +++ b/net/socket.c
> @@ -549,6 +549,8 @@ static inline int __sock_sendmsg_nosec(struct kiocb *iocb, struct socket *sock,
>
> sock_update_classid(sock->sk);
>
> + sock_update_netprioidx(sock->sk);
> +
> si->sock = sock;
> si->scm = NULL;
> si->msg = msg;
> --
> 1.7.6.4
>
^ permalink raw reply
* RE: [PATCH net-next] r8169: Add 64bit statistics
From: David Laight @ 2011-11-17 11:13 UTC (permalink / raw)
To: Junchang Wang, Eric Dumazet; +Cc: Stephen Hemminger, netdev, romieu, nic swsd
In-Reply-To: <CABoNC83U2k=-6-BkJEyWBXfSnEbb-+K8CD1ffqhjA613Tk04tQ@mail.gmail.com>
The 64bit stats update sequence used to get valid
counts on 32bit systems (that can't do locked 64bit
memory access) seems to be:
> u64_stats_update_begin(&sky2->tx_stats.syncp);
> ++sky2->tx_stats.packets;
> sky2->tx_stats.bytes += skb->len;
> u64_stats_update_end(&sky2->tx_stats.syncp);
I'm not sure what the begin/end markers do, but
they need to hold off the readers during updates
and the writers during reads - this is probably
expensive on the update path.
A thought that might work is for the writer to
write the middle bits of the 64 bit walue to
another location, eg:
count = sky2->tx_stats.bytes + skb->len;
sky2->tx_stats.bytes = count;
sky2->tx_stats.bytes_check = count >> 16;
The reader then loops until the two value are
consistent.
I think this doesn't even require a memory barrier
in the ISR since the order of the reads an writes
doesn't matter at all.
David
^ permalink raw reply
* [PATCH v2 7/7] gianfar: add support for wake-on-packet
From: Zhao Chenhui @ 2011-11-17 11:10 UTC (permalink / raw)
To: linuxppc-dev; +Cc: leoli, netdev, afleming
On certain chip like MPC8536 and P1022, system can be waked up from
sleep by user-defined packet and Magic Patcket.(The eTSEC cannot
supports both types of wake-up event simultaneously.) This patch
implements wake-up on user-defined patcket including ARP request
packet and unicast patcket to this station.
When entering suspend state, the gianfar driver sets receive queue
filer table to filter all of packets except ARP request packet and
unicast patcket to this station. The driver temporarily uses the last
receive queue to receive the user defined packet.
In suspend state, the receive part of eTSEC keeps working. When
receiving a user defined packet, it generates an interrupt to
wake up the system.
The rule of the filer table is as below.
if (arp request to local ip address)
accept it to the last queue
elif (unicast packet to local mac address)
accept it to the last queue
else
reject it
endif
Note: The local ip/mac address is the ethernet primary IP/MAC address of
the station. Do not support multiple IP/MAC addresses.
Here is an example of enabling and testing wake up on user defined packet.
ifconfig eth0 10.193.20.169
ethtool -s eth0 wol a
echo standby > /sys/power/state or echo mem > /sys/power/state
Ping from PC host to wake up the station:
ping 10.193.20.169
Signed-off-by: Dave Liu <daveliu@freescale.com>
Signed-off-by: Jin Qing <b24347@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
Acked-by: Andy Fleming <afleming@freescale.com>
---
Changes for v2:
- rework gfar_get_ip(), gfar_config_filer_table(), gfar_suspend() and gfar_resume()
- add support unicast wakeup
- add supported in struct gfar_private
.../devicetree/bindings/net/fsl-tsec-phy.txt | 3 +
drivers/net/ethernet/freescale/gianfar.c | 362 +++++++++++++++++---
drivers/net/ethernet/freescale/gianfar.h | 33 ++-
drivers/net/ethernet/freescale/gianfar_ethtool.c | 52 ++-
4 files changed, 372 insertions(+), 78 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt b/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
index 2c6be03..543e36c 100644
--- a/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
+++ b/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
@@ -56,6 +56,9 @@ Properties:
hardware.
- fsl,magic-packet : If present, indicates that the hardware supports
waking up via magic packet.
+ - fsl,wake-on-filer : If present, indicates that the hardware supports
+ waking up via arp request to local ip address or unicast packet to
+ local mac address.
- bd-stash : If present, indicates that the hardware supports stashing
buffer descriptors in the L2.
- rx-stash-len : Denotes the number of bytes of a received buffer to stash
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 83199fd..991bd47 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -85,6 +85,8 @@
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/in.h>
+#include <linux/inetdevice.h>
+#include <sysdev/fsl_soc.h>
#include <linux/net_tstamp.h>
#include <asm/io.h>
@@ -147,6 +149,17 @@ static void gfar_clear_exact_match(struct net_device *dev);
static void gfar_set_mac_for_addr(struct net_device *dev, int num,
const u8 *addr);
static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static void gfar_schedule_cleanup(struct gfar_priv_grp *gfargrp);
+
+#ifdef CONFIG_PM
+static void gfar_halt_rx(struct net_device *dev);
+static void gfar_rx_start(struct net_device *dev);
+static void gfar_enable_filer(struct net_device *dev);
+static void gfar_disable_filer(struct net_device *dev);
+static void gfar_config_filer_table(struct net_device *dev);
+static void gfar_restore_filer_table(struct net_device *dev);
+static int gfar_get_ip(struct net_device *dev);
+#endif
MODULE_AUTHOR("Freescale Semiconductor, Inc");
MODULE_DESCRIPTION("Gianfar Ethernet Driver");
@@ -751,7 +764,6 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
FSL_GIANFAR_DEV_HAS_PADDING |
FSL_GIANFAR_DEV_HAS_CSUM |
FSL_GIANFAR_DEV_HAS_VLAN |
- FSL_GIANFAR_DEV_HAS_MAGIC_PACKET |
FSL_GIANFAR_DEV_HAS_EXTENDED_HASH |
FSL_GIANFAR_DEV_HAS_TIMER;
@@ -763,8 +775,19 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
else
priv->interface = PHY_INTERFACE_MODE_MII;
- if (of_get_property(np, "fsl,magic-packet", NULL))
+ /* Init Wake-on-LAN */
+ priv->wol_opts = 0;
+ priv->wol_supported = 0;
+ if (of_get_property(np, "fsl,magic-packet", NULL)) {
priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET;
+ priv->wol_supported |= GIANFAR_WOL_MAGIC;
+ }
+
+ if (of_get_property(np, "fsl,wake-on-filer", NULL)) {
+ priv->device_flags |= FSL_GIANFAR_DEV_HAS_WAKE_ON_FILER;
+ priv->wol_supported |= GIANFAR_WOL_ARP;
+ priv->wol_supported |= GIANFAR_WOL_UCAST;
+ }
priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
@@ -1168,8 +1191,10 @@ static int gfar_probe(struct platform_device *ofdev)
goto register_fail;
}
- device_init_wakeup(&dev->dev,
- priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
+ if (priv->wol_supported) {
+ device_set_wakeup_capable(&ofdev->dev, true);
+ device_set_wakeup_enable(&ofdev->dev, false);
+ }
/* fill out IRQ number and name fields */
len_devname = strlen(dev->name);
@@ -1260,6 +1285,143 @@ static int gfar_remove(struct platform_device *ofdev)
}
#ifdef CONFIG_PM
+static void gfar_enable_filer(struct net_device *dev)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
+ u32 temp;
+
+ lock_rx_qs(priv);
+
+ temp = gfar_read(®s->rctrl);
+ temp &= ~(RCTRL_FSQEN | RCTRL_PRSDEP_MASK);
+ temp |= RCTRL_FILREN | RCTRL_PRSDEP_L2L3;
+ gfar_write(®s->rctrl, temp);
+
+ unlock_rx_qs(priv);
+}
+
+static void gfar_disable_filer(struct net_device *dev)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
+ u32 temp;
+
+ lock_rx_qs(priv);
+
+ temp = gfar_read(®s->rctrl);
+ temp &= ~RCTRL_FILREN;
+ gfar_write(®s->rctrl, temp);
+
+ unlock_rx_qs(priv);
+}
+
+static int gfar_get_ip(struct net_device *dev)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+ struct in_device *in_dev;
+ int ret = -ENOENT;
+
+ in_dev = in_dev_get(dev);
+ if (!in_dev)
+ return ret;
+
+ /* Get the primary IP address */
+ for_primary_ifa(in_dev) {
+ priv->ip_addr = ifa->ifa_address;
+ ret = 0;
+ break;
+ } endfor_ifa(in_dev);
+
+ in_dev_put(in_dev);
+ return ret;
+}
+
+static void gfar_restore_filer_table(struct net_device *dev)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+ u32 rqfcr, rqfpr;
+ int i;
+
+ lock_rx_qs(priv);
+
+ for (i = 0; i <= MAX_FILER_IDX; i++) {
+ rqfcr = priv->ftp_rqfcr[i];
+ rqfpr = priv->ftp_rqfpr[i];
+ gfar_write_filer(priv, i, rqfcr, rqfpr);
+ }
+
+ unlock_rx_qs(priv);
+}
+
+static void gfar_config_filer_table(struct net_device *dev)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+ u32 dest_mac_addr;
+ u32 rqfcr, rqfpr;
+ u8 rqfcr_queue = priv->num_rx_queues - 1;
+ unsigned int index;
+
+ if (gfar_get_ip(dev)) {
+ netif_err(priv, wol, dev, "WOL: get the ip address error\n");
+ return;
+ }
+
+ lock_rx_qs(priv);
+
+ /* init filer table */
+ rqfcr = RQFCR_RJE | RQFCR_CMP_MATCH;
+ rqfpr = 0x0;
+ for (index = 0; index <= MAX_FILER_IDX; index++)
+ gfar_write_filer(priv, index, rqfcr, rqfpr);
+
+ index = 0;
+ if (priv->wol_opts & GIANFAR_WOL_ARP) {
+ /* ARP request filer, filling the packet to the last queue */
+ rqfcr = (rqfcr_queue << 10) | RQFCR_AND |
+ RQFCR_CMP_EXACT | RQFCR_PID_MASK;
+ rqfpr = RQFPR_ARQ;
+ gfar_write_filer(priv, index++, rqfcr, rqfpr);
+
+ rqfcr = (rqfcr_queue << 10) | RQFCR_AND |
+ RQFCR_CMP_EXACT | RQFCR_PID_PARSE;
+ rqfpr = RQFPR_ARQ;
+ gfar_write_filer(priv, index++, rqfcr, rqfpr);
+
+ /*
+ * DEST_IP address in ARP packet,
+ * filling it to the last queue.
+ */
+ rqfcr = (rqfcr_queue << 10) | RQFCR_AND |
+ RQFCR_CMP_EXACT | RQFCR_PID_MASK;
+ rqfpr = FPR_FILER_MASK;
+ gfar_write_filer(priv, index++, rqfcr, rqfpr);
+
+ rqfcr = (rqfcr_queue << 10) | RQFCR_GPI |
+ RQFCR_CMP_EXACT | RQFCR_PID_DIA;
+ rqfpr = priv->ip_addr;
+ gfar_write_filer(priv, index++, rqfcr, rqfpr);
+ }
+
+ if (priv->wol_opts & GIANFAR_WOL_UCAST) {
+ /* Unicast packet, filling it to the last queue */
+ dest_mac_addr = (dev->dev_addr[0] << 16) |
+ (dev->dev_addr[1] << 8) | dev->dev_addr[2];
+ rqfcr = (rqfcr_queue << 10) | RQFCR_AND |
+ RQFCR_CMP_EXACT | RQFCR_PID_DAH;
+ rqfpr = dest_mac_addr;
+ gfar_write_filer(priv, index++, rqfcr, rqfpr);
+
+ dest_mac_addr = (dev->dev_addr[3] << 16) |
+ (dev->dev_addr[4] << 8) | dev->dev_addr[5];
+ rqfcr = (rqfcr_queue << 10) | RQFCR_GPI |
+ RQFCR_CMP_EXACT | RQFCR_PID_DAL;
+ rqfpr = dest_mac_addr;
+ gfar_write_filer(priv, index++, rqfcr, rqfpr);
+ }
+
+ unlock_rx_qs(priv);
+}
static int gfar_suspend(struct device *dev)
{
@@ -1269,48 +1431,43 @@ static int gfar_suspend(struct device *dev)
unsigned long flags;
u32 tempval;
- int magic_packet = priv->wol_en &&
- (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
-
netif_device_detach(ndev);
- if (netif_running(ndev)) {
-
- local_irq_save(flags);
- lock_tx_qs(priv);
- lock_rx_qs(priv);
-
- gfar_halt_nodisable(ndev);
-
- /* Disable Tx, and Rx if wake-on-LAN is disabled. */
- tempval = gfar_read(®s->maccfg1);
-
- tempval &= ~MACCFG1_TX_EN;
+ if (!netif_running(ndev))
+ return 0;
- if (!magic_packet)
- tempval &= ~MACCFG1_RX_EN;
+ local_irq_save(flags);
+ lock_tx_qs(priv);
+ lock_rx_qs(priv);
- gfar_write(®s->maccfg1, tempval);
+ gfar_halt(ndev);
- unlock_rx_qs(priv);
- unlock_tx_qs(priv);
- local_irq_restore(flags);
+ unlock_rx_qs(priv);
+ unlock_tx_qs(priv);
+ local_irq_restore(flags);
- disable_napi(priv);
+ disable_napi(priv);
- if (magic_packet) {
- /* Enable interrupt on Magic Packet */
- gfar_write(®s->imask, IMASK_MAG);
+ if (!priv->wol_opts && priv->phydev) {
+ phy_stop(priv->phydev);
+ return 0;
+ }
- /* Enable Magic Packet mode */
- tempval = gfar_read(®s->maccfg2);
- tempval |= MACCFG2_MPEN;
- gfar_write(®s->maccfg2, tempval);
- } else {
- phy_stop(priv->phydev);
- }
+ mpc85xx_pmc_set_wake(priv->ofdev, 1);
+ if (priv->wol_opts & GIANFAR_WOL_MAGIC) {
+ /* Enable Magic Packet mode */
+ tempval = gfar_read(®s->maccfg2);
+ tempval |= MACCFG2_MPEN;
+ gfar_write(®s->maccfg2, tempval);
}
+ if (priv->wol_opts & (GIANFAR_WOL_ARP | GIANFAR_WOL_UCAST)) {
+ mpc85xx_pmc_set_lossless_ethernet(1);
+ gfar_disable_filer(ndev);
+ gfar_config_filer_table(ndev);
+ gfar_enable_filer(ndev);
+ }
+ gfar_rx_start(ndev);
return 0;
}
@@ -1320,39 +1477,49 @@ static int gfar_resume(struct device *dev)
struct net_device *ndev = priv->ndev;
struct gfar __iomem *regs = priv->gfargrp[0].regs;
unsigned long flags;
- u32 tempval;
- int magic_packet = priv->wol_en &&
- (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
+ u32 tempval, i;
if (!netif_running(ndev)) {
netif_device_attach(ndev);
return 0;
}
- if (!magic_packet && priv->phydev)
+ if (!priv->wol_opts && priv->phydev) {
phy_start(priv->phydev);
+ goto out;
+ }
+
+ mpc85xx_pmc_set_wake(priv->ofdev, 0);
- /* Disable Magic Packet mode, in case something
- * else woke us up.
- */
local_irq_save(flags);
- lock_tx_qs(priv);
lock_rx_qs(priv);
-
- tempval = gfar_read(®s->maccfg2);
- tempval &= ~MACCFG2_MPEN;
- gfar_write(®s->maccfg2, tempval);
-
- gfar_start(ndev);
-
+ gfar_halt_rx(ndev);
unlock_rx_qs(priv);
- unlock_tx_qs(priv);
local_irq_restore(flags);
- netif_device_attach(ndev);
+ if (priv->wol_opts & (GIANFAR_WOL_ARP | GIANFAR_WOL_UCAST)) {
+ mpc85xx_pmc_set_lossless_ethernet(0);
+ gfar_disable_filer(ndev);
+ gfar_restore_filer_table(ndev);
+ }
+
+ if (priv->wol_opts & GIANFAR_WOL_MAGIC) {
+ /* Disable Magic Packet mode */
+ tempval = gfar_read(®s->maccfg2);
+ tempval &= ~MACCFG2_MPEN;
+ gfar_write(®s->maccfg2, tempval);
+ }
+out:
+ gfar_start(ndev);
+ netif_device_attach(ndev);
enable_napi(priv);
+ if (priv->wol_opts & (GIANFAR_WOL_ARP | GIANFAR_WOL_UCAST)) {
+ /* send requests to process the received packets */
+ for (i = 0; i < priv->num_grps; i++)
+ gfar_schedule_cleanup(&priv->gfargrp[i]);
+ }
return 0;
}
@@ -1602,6 +1769,48 @@ static int __gfar_is_rx_idle(struct gfar_private *priv)
return 0;
}
+#ifdef CONFIG_PM
+/* Halt the receive queues */
+static void gfar_halt_rx(struct net_device *dev)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
+ u32 tempval;
+ int i = 0;
+
+ for (i = 0; i < priv->num_grps; i++) {
+ regs = priv->gfargrp[i].regs;
+ /* Mask all interrupts */
+ gfar_write(®s->imask, IMASK_INIT_CLEAR);
+
+ /* Clear all interrupts */
+ gfar_write(®s->ievent, IEVENT_INIT_CLEAR);
+ }
+
+ regs = priv->gfargrp[0].regs;
+ /* Stop the DMA, and wait for it to stop */
+ tempval = gfar_read(®s->dmactrl);
+ if ((tempval & DMACTRL_GRS) != DMACTRL_GRS) {
+ int ret;
+
+ tempval |= DMACTRL_GRS;
+ gfar_write(®s->dmactrl, tempval);
+
+ do {
+ ret = spin_event_timeout(((gfar_read(®s->ievent) &
+ IEVENT_GRSC) == IEVENT_GRSC), 1000000, 0);
+ if (!ret && !(gfar_read(®s->ievent) & IEVENT_GRSC))
+ ret = __gfar_is_rx_idle(priv);
+ } while (!ret);
+ }
+
+ /* Disable Rx in MACCFG1 */
+ tempval = gfar_read(®s->maccfg1);
+ tempval &= ~MACCFG1_RX_EN;
+ gfar_write(®s->maccfg1, tempval);
+}
+#endif
+
/* Halt the receive and transmit queues */
static void gfar_halt_nodisable(struct net_device *dev)
{
@@ -1808,6 +2017,40 @@ void gfar_start(struct net_device *dev)
dev->trans_start = jiffies; /* prevent tx timeout */
}
+#ifdef CONFIG_PM
+void gfar_rx_start(struct net_device *dev)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
+ u32 tempval;
+ int i = 0;
+
+ /* Enable Rx in MACCFG1 */
+ tempval = gfar_read(®s->maccfg1);
+ tempval |= MACCFG1_RX_EN;
+ gfar_write(®s->maccfg1, tempval);
+
+ /* Initialize DMACTRL to have WWR and WOP */
+ tempval = gfar_read(®s->dmactrl);
+ tempval |= DMACTRL_INIT_SETTINGS;
+ gfar_write(®s->dmactrl, tempval);
+
+ /* Make sure we aren't stopped */
+ tempval = gfar_read(®s->dmactrl);
+ tempval &= ~DMACTRL_GRS;
+ gfar_write(®s->dmactrl, tempval);
+
+ for (i = 0; i < priv->num_grps; i++) {
+ regs = priv->gfargrp[i].regs;
+ /* Clear RHLT, so that the DMA starts polling now */
+ gfar_write(®s->rstat, priv->gfargrp[i].rstat);
+
+ /* Unmask the interrupts we look for */
+ gfar_write(®s->imask, IMASK_DEFAULT);
+ }
+}
+#endif
+
void gfar_configure_coalescing(struct gfar_private *priv,
unsigned long tx_mask, unsigned long rx_mask)
{
@@ -1970,7 +2213,7 @@ static int gfar_enet_open(struct net_device *dev)
netif_tx_start_all_queues(dev);
- device_set_wakeup_enable(&dev->dev, priv->wol_en);
+ device_set_wakeup_enable(&priv->ofdev->dev, priv->wol_opts);
return err;
}
@@ -2657,6 +2900,17 @@ static inline void count_errors(unsigned short status, struct net_device *dev)
irqreturn_t gfar_receive(int irq, void *grp_id)
{
+ struct gfar_priv_grp *gfargrp = grp_id;
+ struct gfar __iomem *regs = gfargrp->regs;
+ u32 ievent;
+
+ ievent = gfar_read(®s->ievent);
+
+ if ((ievent & IEVENT_FGPI) == IEVENT_FGPI) {
+ gfar_write(®s->ievent, ievent & IEVENT_RX_MASK);
+ return IRQ_HANDLED;
+ }
+
gfar_schedule_cleanup((struct gfar_priv_grp *)grp_id);
return IRQ_HANDLED;
}
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h
index 9aa4377..1abebc4 100644
--- a/drivers/net/ethernet/freescale/gianfar.h
+++ b/drivers/net/ethernet/freescale/gianfar.h
@@ -232,6 +232,13 @@ extern const char gfar_driver_version[];
#define RQUEUE_EN7 0x00000001
#define RQUEUE_EN_ALL 0x000000FF
+/* Wake-On-Lan options */
+#define GIANFAR_WOL_UCAST 0x00000001 /* Unicast wakeup */
+#define GIANFAR_WOL_MCAST 0x00000002 /* Multicast wakeup */
+#define GIANFAR_WOL_BCAST 0x00000004 /* Broadcase wakeup */
+#define GIANFAR_WOL_ARP 0x00000008 /* ARP request wakeup */
+#define GIANFAR_WOL_MAGIC 0x00000010 /* Magic packet wakeup */
+
/* Init to do tx snooping for buffers and descriptors */
#define DMACTRL_INIT_SETTINGS 0x000000c3
#define DMACTRL_GRS 0x00000010
@@ -277,11 +284,15 @@ extern const char gfar_driver_version[];
#define RCTRL_PAL_MASK 0x001f0000
#define RCTRL_VLEX 0x00002000
#define RCTRL_FILREN 0x00001000
+#define RCTRL_FSQEN 0x00000800
#define RCTRL_GHTX 0x00000400
#define RCTRL_IPCSEN 0x00000200
#define RCTRL_TUCSEN 0x00000100
#define RCTRL_PRSDEP_MASK 0x000000c0
#define RCTRL_PRSDEP_INIT 0x000000c0
+#define RCTRL_PRSDEP_L2 0x00000040
+#define RCTRL_PRSDEP_L2L3 0x00000080
+#define RCTRL_PRSDEP_L2L3L4 0x000000c0
#define RCTRL_PRSFM 0x00000020
#define RCTRL_PROM 0x00000008
#define RCTRL_EMEN 0x00000002
@@ -327,18 +338,20 @@ extern const char gfar_driver_version[];
#define IEVENT_MAG 0x00000800
#define IEVENT_GRSC 0x00000100
#define IEVENT_RXF0 0x00000080
+#define IEVENT_FGPI 0x00000010
#define IEVENT_FIR 0x00000008
#define IEVENT_FIQ 0x00000004
#define IEVENT_DPE 0x00000002
#define IEVENT_PERR 0x00000001
-#define IEVENT_RX_MASK (IEVENT_RXB0 | IEVENT_RXF0 | IEVENT_BSY)
+#define IEVENT_RX_MASK (IEVENT_RXB0 | IEVENT_RXF0 | \
+ IEVENT_FGPI | IEVENT_BSY)
#define IEVENT_TX_MASK (IEVENT_TXB | IEVENT_TXF)
#define IEVENT_RTX_MASK (IEVENT_RX_MASK | IEVENT_TX_MASK)
#define IEVENT_ERR_MASK \
-(IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \
- IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \
- | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR \
- | IEVENT_MAG | IEVENT_BABR)
+ (IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \
+ IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC | \
+ IEVENT_CRL | IEVENT_XFUN | IEVENT_FIR | IEVENT_FIQ | \
+ IEVENT_DPE | IEVENT_PERR | IEVENT_MAG | IEVENT_BABR)
#define IMASK_INIT_CLEAR 0x00000000
#define IMASK_BABR 0x80000000
@@ -359,14 +372,15 @@ extern const char gfar_driver_version[];
#define IMASK_MAG 0x00000800
#define IMASK_GRSC 0x00000100
#define IMASK_RXFEN0 0x00000080
+#define IMASK_FGPI 0x00000010
#define IMASK_FIR 0x00000008
#define IMASK_FIQ 0x00000004
#define IMASK_DPE 0x00000002
#define IMASK_PERR 0x00000001
#define IMASK_DEFAULT (IMASK_TXEEN | IMASK_TXFEN | IMASK_TXBEN | \
IMASK_RXFEN0 | IMASK_BSY | IMASK_EBERR | IMASK_BABR | \
- IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \
- | IMASK_PERR)
+ IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_FGPI | \
+ IMASK_FIR | IMASK_FIQ | IMASK_DPE | IMASK_PERR | IMASK_MAG)
#define IMASK_RTX_DISABLED ((~(IMASK_RXFEN0 | IMASK_TXFEN | IMASK_BSY)) \
& IMASK_DEFAULT)
@@ -883,6 +897,7 @@ struct gfar {
#define FSL_GIANFAR_DEV_HAS_BD_STASHING 0x00000200
#define FSL_GIANFAR_DEV_HAS_BUF_STASHING 0x00000400
#define FSL_GIANFAR_DEV_HAS_TIMER 0x00000800
+#define FSL_GIANFAR_DEV_HAS_WAKE_ON_FILER 0x00001000
#if (MAXGROUPS == 2)
#define DEFAULT_MAPPING 0xAA
@@ -1115,6 +1130,10 @@ struct gfar_private {
struct work_struct reset_task;
+ u32 ip_addr;
+ u32 wol_opts;
+ u32 wol_supported;
+
/* Network Statistics */
struct gfar_extra_stats extra_stats;
diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c
index 212736b..296e762 100644
--- a/drivers/net/ethernet/freescale/gianfar_ethtool.c
+++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c
@@ -29,6 +29,7 @@
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -577,32 +578,49 @@ static void gfar_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct gfar_private *priv = netdev_priv(dev);
- if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) {
- wol->supported = WAKE_MAGIC;
- wol->wolopts = priv->wol_en ? WAKE_MAGIC : 0;
- } else {
- wol->supported = wol->wolopts = 0;
- }
+ wol->supported = 0;
+ wol->wolopts = 0;
+
+ if (!priv->wol_supported || !device_can_wakeup(&priv->ofdev->dev))
+ return;
+
+ if (priv->wol_supported & GIANFAR_WOL_MAGIC)
+ wol->supported |= WAKE_MAGIC;
+
+ if (priv->wol_supported & GIANFAR_WOL_ARP)
+ wol->supported |= WAKE_ARP;
+
+ if (priv->wol_supported & GIANFAR_WOL_UCAST)
+ wol->supported |= WAKE_UCAST;
+
+ if (priv->wol_opts & GIANFAR_WOL_MAGIC)
+ wol->wolopts |= WAKE_MAGIC;
+
+ if (priv->wol_opts & GIANFAR_WOL_ARP)
+ wol->wolopts |= WAKE_ARP;
+
+ if (priv->wol_opts & GIANFAR_WOL_UCAST)
+ wol->wolopts |= WAKE_UCAST;
}
static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct gfar_private *priv = netdev_priv(dev);
- unsigned long flags;
- if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) &&
- wol->wolopts != 0)
- return -EINVAL;
-
- if (wol->wolopts & ~WAKE_MAGIC)
- return -EINVAL;
+ if (!priv->wol_supported || !device_can_wakeup(&priv->ofdev->dev) ||
+ (wol->wolopts & ~(WAKE_MAGIC | WAKE_ARP | WAKE_UCAST)))
+ return -EOPNOTSUPP;
- device_set_wakeup_enable(&dev->dev, wol->wolopts & WAKE_MAGIC);
+ priv->wol_opts = 0;
- spin_lock_irqsave(&priv->bflock, flags);
- priv->wol_en = !!device_may_wakeup(&dev->dev);
- spin_unlock_irqrestore(&priv->bflock, flags);
+ if (wol->wolopts & WAKE_MAGIC)
+ priv->wol_opts |= GIANFAR_WOL_MAGIC;
+ if (wol->wolopts & WAKE_ARP)
+ priv->wol_opts |= GIANFAR_WOL_ARP;
+ if (wol->wolopts & WAKE_UCAST)
+ priv->wol_opts |= GIANFAR_WOL_UCAST;
+ device_set_wakeup_enable(&priv->ofdev->dev, (u32)priv->wol_opts);
return 0;
}
#endif
--
1.6.4.1
^ permalink raw reply related
* Re: [PATCH] net: use jump_label to shortcut RPS if not setup
From: Eric Dumazet @ 2011-11-17 11:08 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Tom Herbert
In-Reply-To: <1321526027.2751.16.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
Le jeudi 17 novembre 2011 à 11:33 +0100, Eric Dumazet a écrit :
> Most machines dont use RPS/RFS, and pay a fair amount of instructions in
> netif_receive_skb() / get_rps_cpu() just to discover RPS/RFS is not
> setup.
>
> Add a jump_label named rps_needed.
>
> If no device rps_map or global rps_sock_flow_table is setup,
> netif_receive_skb() does a single instruction instead of many ones,
> including conditional jumps.
>
> jmp +0 (if CONFIG_JUMP_LABEL=y)
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> CC: Tom Herbert <therbert@google.com>
> ---
I'll send a V2 to take care of netif_rx() as well.
^ permalink raw reply
* Re: [PATCH net-next] r8169: Add 64bit statistics
From: Junchang Wang @ 2011-11-17 10:59 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Stephen Hemminger, netdev, romieu, nic swsd
In-Reply-To: <1321517516.3274.40.camel@edumazet-laptop>
> Yes, look at sky2.c for a template
>
> drivers/net/ethernet/marvell/sky2.c contains code like that
> (different syncp for rx/tx)
>
> TX path:
> u64_stats_update_begin(&sky2->tx_stats.syncp);
> ++sky2->tx_stats.packets;
> sky2->tx_stats.bytes += skb->len;
> u64_stats_update_end(&sky2->tx_stats.syncp);
>
>
> RX path:
>
> u64_stats_update_begin(&sky2->rx_stats.syncp);
> sky2->rx_stats.packets += packets;
> sky2->rx_stats.bytes += bytes;
> u64_stats_update_end(&sky2->rx_stats.syncp);
>
Thanks, Eric.
I'm still confused about why we need two sync entries. Please correct
me if I'm wrong.
Take r8169 for example, All statistic entries are updated in
rtl8169_rx_interrupt() or rtl8169_tx_interrupt(). Those two functions
are called in rtl8169_poll().
As far as I know, rtl8169_poll() is protected by NAPI_STATE_SCHED bit
to run on a single core at one moment. So there is not compulsory to
use two sync entries.
One benefit from two sync is that readers can avoid many retries.
Thanks.
--
--Junchang
^ permalink raw reply
* Re: [PATCH net-next] r8169: Add 64bit statistics
From: Eric Dumazet @ 2011-11-17 10:51 UTC (permalink / raw)
To: Francois Romieu; +Cc: Junchang Wang, nic_swsd, netdev
In-Reply-To: <20111117093635.GA9112@electric-eye.fr.zoreil.com>
Le jeudi 17 novembre 2011 à 10:36 +0100, Francois Romieu a écrit :
> Junchang Wang <junchangwang@gmail.com> :
> >
> > Switch to use ndo_get_stats64 to get 64bit statistics.
> > Per cpu data is used to avoid lock operations.
>
> The 816x chipsets have hardware stats registers. The driver already
> use them. Please use them more.
>
I would like to mention a possible bias.
I know for that tg3 includes in RX counters frames/bytes that were
dropped (because napi handler couldnot keep up with the load)
They also include FCS in the byte count.
When using software counters, we can compare "ethtool -S" and "ifconfig"
ones.
But generaly speaking, if hardware stats are available we should use
them and save few instructions per packet ;)
^ permalink raw reply
* [PATCH] net: use jump_label to shortcut RPS if not setup
From: Eric Dumazet @ 2011-11-17 10:33 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Tom Herbert
Most machines dont use RPS/RFS, and pay a fair amount of instructions in
netif_receive_skb() / get_rps_cpu() just to discover RPS/RFS is not
setup.
Add a jump_label named rps_needed.
If no device rps_map or global rps_sock_flow_table is setup,
netif_receive_skb() does a single instruction instead of many ones,
including conditional jumps.
jmp +0 (if CONFIG_JUMP_LABEL=y)
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Tom Herbert <therbert@google.com>
---
include/linux/netdevice.h | 5 +++++
net/core/dev.c | 14 ++++++--------
net/core/net-sysfs.c | 7 +++++--
net/core/sysctl_net_core.c | 9 +++++++--
4 files changed, 23 insertions(+), 12 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 4d5698a..0bbe030 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -214,6 +214,11 @@ enum {
#include <linux/cache.h>
#include <linux/skbuff.h>
+#ifdef CONFIG_RPS
+#include <linux/jump_label.h>
+extern struct jump_label_key rps_needed;
+#endif
+
struct neighbour;
struct neigh_parms;
struct sk_buff;
diff --git a/net/core/dev.c b/net/core/dev.c
index 26c49d5..4c3942c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2711,6 +2711,8 @@ EXPORT_SYMBOL(__skb_get_rxhash);
struct rps_sock_flow_table __rcu *rps_sock_flow_table __read_mostly;
EXPORT_SYMBOL(rps_sock_flow_table);
+struct jump_label_key rps_needed __read_mostly;
+
static struct rps_dev_flow *
set_rps_cpu(struct net_device *dev, struct sk_buff *skb,
struct rps_dev_flow *rflow, u16 next_cpu)
@@ -3359,7 +3361,7 @@ int netif_receive_skb(struct sk_buff *skb)
return NET_RX_SUCCESS;
#ifdef CONFIG_RPS
- {
+ if (static_branch(&rps_needed)) {
struct rps_dev_flow voidflow, *rflow = &voidflow;
int cpu, ret;
@@ -3370,16 +3372,12 @@ int netif_receive_skb(struct sk_buff *skb)
if (cpu >= 0) {
ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
rcu_read_unlock();
- } else {
- rcu_read_unlock();
- ret = __netif_receive_skb(skb);
+ return ret;
}
-
- return ret;
+ rcu_read_unlock();
}
-#else
- return __netif_receive_skb(skb);
#endif
+ return __netif_receive_skb(skb);
}
EXPORT_SYMBOL(netif_receive_skb);
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 602b141..db6c2f8 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -606,9 +606,12 @@ static ssize_t store_rps_map(struct netdev_rx_queue *queue,
rcu_assign_pointer(queue->rps_map, map);
spin_unlock(&rps_map_lock);
- if (old_map)
+ if (map)
+ jump_label_inc(&rps_needed);
+ if (old_map) {
kfree_rcu(old_map, rcu);
-
+ jump_label_dec(&rps_needed);
+ }
free_cpumask_var(mask);
return len;
}
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index 77a65f0..d05559d 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -68,8 +68,13 @@ static int rps_sock_flow_sysctl(ctl_table *table, int write,
if (sock_table != orig_sock_table) {
rcu_assign_pointer(rps_sock_flow_table, sock_table);
- synchronize_rcu();
- vfree(orig_sock_table);
+ if (sock_table)
+ jump_label_inc(&rps_needed);
+ if (orig_sock_table) {
+ jump_label_dec(&rps_needed);
+ synchronize_rcu();
+ vfree(orig_sock_table);
+ }
}
}
^ permalink raw reply related
* Re: [PATCH 1/6] net: add the nwhwconfig support
From: Giuseppe CAVALLARO @ 2011-11-17 10:17 UTC (permalink / raw)
To: David Miller
Cc: netdev, mamoroso, shiraz.hashim, armando.visconti, stuart.menefy
In-Reply-To: <20111117.030625.229541498275597867.davem@davemloft.net>
Hello David,
On 11/17/2011 9:06 AM, David Miller wrote:
> From: Giuseppe CAVALLARO<peppe.cavallaro@st.com>
> Date: Thu, 17 Nov 2011 09:01:40 +0100
>
>> Network drivers support hardware level configuration via utilities such as
>> ifconfig, ethtool and mii-tool. However sometimes these settings need to be
>> adjusted before a file system is available (typically if the root file system
>> uses NFS).
>
> No way, use an initial ramdisk.
Yes I agree with you that ramdisk is a solution :-) but this driver is
actually helping many users of stmmac on several platforms.
Hmm, I also think it can be useful.
For example, in my environment, I need to continuously boot a Kernel on
ST boxes and mount a rootFS via NFS to have the access to the full
(arm/sh - glibc/uclibc) distributions (to use several packages for
networking tests, X system etc).
This driver helps me to go faster in the normal development.
I am aware that starting with a ramdisk I could do that but with extra
steps and configuration.
I mean, I want to pass all my network configuration in command line,
such as ip= option, and this driver should not be in conflict with this
logic.
With this small driver it's possible to force link speed and duplex
modes when the kernel boots and this help me on validating HW and
performing tests as well.
In any case, the driver is on the mailing list and other people can test
it and provide feedback and enhancements.
Best Regards
Peppe
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [patch net-next 3/3] team: replicate options on register
From: Eric Dumazet @ 2011-11-17 10:03 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, bhutchings, shemminger, andy, fbl, jzupka, ivecera
In-Reply-To: <1321524023.2751.1.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
Le jeudi 17 novembre 2011 à 11:00 +0100, Eric Dumazet a écrit :
> If you know the absolute limit of option_count, you could use
>
> struct team_option *dst_opts[OPTION_COUNT_MAX];
>
> If not, then a kmalloc()/kfree() is probably needed ;)
>
>
Sorry, forgot to include the link explaining Linus opinion on
variable-length arrays
https://lkml.org/lkml/2011/10/23/25
^ permalink raw reply
* Re: [PATCH 1/3] NET: MIPS: lantiq: make etop ethernet work on ase/ar9
From: John Crispin @ 2011-11-17 11:00 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20111116.220220.2004448468476437215.davem@davemloft.net>
On 17/11/11 04:02, David Miller wrote:
> From: John Crispin <blogic@openwrt.org>
> Date: Wed, 16 Nov 2011 15:41:46 +0100
>
>> Extend the driver to handle the different DMA channel layout for AR9 and
>> Amazon-SE SoCs. The patch also adds support for the integrated PHY found
>> on Amazon-SE and the gigabit switch found inside the AR9.
>>
>> Signed-off-by: John Crispin <blogic@openwrt.org>
>> Cc: netdev@vger.kernel.org
> Since these patches (at least partially) modify MIPS files, please submit
> them via the MIPS maintainer.
>
> Feel free to add:
>
> Acked-by: David S. Miller <davem@davemloft.net>
>
Thank you !
^ permalink raw reply
* Re: [patch net-next 3/3] team: replicate options on register
From: Eric Dumazet @ 2011-11-17 10:00 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, bhutchings, shemminger, andy, fbl, jzupka, ivecera
In-Reply-To: <20111117095729.GA2093@minipsycho>
Le jeudi 17 novembre 2011 à 10:57 +0100, Jiri Pirko a écrit :
> Thu, Nov 17, 2011 at 09:32:16AM CET, eric.dumazet@gmail.com wrote:
> >Le mercredi 16 novembre 2011 à 22:09 +0100, Jiri Pirko a écrit :
> >
> >> +
> >> +int team_options_register(struct team *team,
> >> + const struct team_option *option,
> >> + size_t option_count)
> >> {
> >> int i;
> >> + struct team_option *dst_opts[option_count];
> >> + int err;
> >
> >This kind of construct will trigger static analyzer alerts...
>
>
> I thought this is ok to do in kernel. Should I replace that with
> kmalloc/kfree?
If you know the absolute limit of option_count, you could use
struct team_option *dst_opts[OPTION_COUNT_MAX];
If not, then a kmalloc()/kfree() is probably needed ;)
^ permalink raw reply
* Re: [patch net-next 3/3] team: replicate options on register
From: Jiri Pirko @ 2011-11-17 9:57 UTC (permalink / raw)
To: Eric Dumazet
Cc: netdev, davem, bhutchings, shemminger, andy, fbl, jzupka, ivecera
In-Reply-To: <1321518736.3274.45.camel@edumazet-laptop>
Thu, Nov 17, 2011 at 09:32:16AM CET, eric.dumazet@gmail.com wrote:
>Le mercredi 16 novembre 2011 à 22:09 +0100, Jiri Pirko a écrit :
>
>> +
>> +int team_options_register(struct team *team,
>> + const struct team_option *option,
>> + size_t option_count)
>> {
>> int i;
>> + struct team_option *dst_opts[option_count];
>> + int err;
>
>This kind of construct will trigger static analyzer alerts...
I thought this is ok to do in kernel. Should I replace that with
kmalloc/kfree?
>
>
>
>
^ permalink raw reply
* Re: [PATCH] r8169: add module param for control of ASPM disable
From: Francois Romieu @ 2011-11-17 9:37 UTC (permalink / raw)
To: Todd Broch
Cc: Matthew Garrett, Realtek linux nic maintainers, netdev,
Hayes Wang
In-Reply-To: <CA+iF6Rog3ptpmQZzhcRODmZUKN18_uw5t9xfpQjbJ86qKUA0eQ@mail.gmail.com>
Todd Broch <tbroch@chromium.org> :
[...]
> I've tested on a Mobile Sandybridge platform only as I presently don't have
> access to any other systems w/ the r8169 h/w.
Sorry for the lack of specificity : the XID line from the r8169 driver would
be welcome. It should look like:
[ 6.315053] r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
[ 6.315287] r8169 0000:03:00.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16
[ 6.315568] r8169 0000:03:00.0: setting latency timer to 64
[ 6.315663] r8169 0000:03:00.0: irq 49 for MSI/MSI-X
[ 6.315834] r8169 0000:03:00.0: eth0: RTL8168evl/8111evl at 0xffffc90000676000, 00:e0:4c:68:00:1f, XID 0c900800 IRQ 49
^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^
Thanks.
--
Ueimor
^ permalink raw reply
* Re: [PATCH net-next] r8169: Add 64bit statistics
From: Francois Romieu @ 2011-11-17 9:36 UTC (permalink / raw)
To: Junchang Wang; +Cc: nic_swsd, eric.dumazet, netdev
In-Reply-To: <20111117064826.GA4429@Desktop-Junchang>
Junchang Wang <junchangwang@gmail.com> :
>
> Switch to use ndo_get_stats64 to get 64bit statistics.
> Per cpu data is used to avoid lock operations.
The 816x chipsets have hardware stats registers. The driver already
use them. Please use them more.
--
Ueimor
^ permalink raw reply
* Re: [PATCH 1/2] net: add network priority cgroup infrastructure
From: WANG Cong @ 2011-11-17 9:29 UTC (permalink / raw)
To: netdev
In-Reply-To: <1321476666-8225-2-git-send-email-nhorman@tuxdriver.com>
On Wed, 16 Nov 2011 15:51:05 -0500, Neil Horman wrote:
> +static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp)
> +{
> + struct cgroup_netprio_state *cs;
> + struct net_device *dev;
> +
> + cs = cgrp_netprio_state(cgrp);
> + rtnl_lock();
> + for_each_netdev(&init_net, dev) {
> + if (dev->priomap)
> + dev->priomap->priomap[cs->prioidx] = 0;
> + }
> + rtnl_unlock();
> + put_prioidx(cs->prioidx);
> +out_free:
> + kfree(cs);
> +}
'out_free' is unused.
> +
> +static int write_priomap(struct cgroup *cgrp, struct cftype *cft,
> + const char *buffer)
> +{
> + char *devname = kstrdup(buffer, GFP_KERNEL);
> + int ret = -EINVAL;
> + u32 prioidx = cgrp_netprio_state(cgrp)->prioidx;
> + unsigned long priority;
> + char *priostr;
> + struct net_device *dev;
> +
> + devname = kstrdup(buffer, GFP_KERNEL);
kstrdup() is called twice...
Thanks.
^ permalink raw reply
* [PATCH v7] Phonet: set the pipe handle using setsockopt
From: Hemant Vilas RAMDASI @ 2011-11-17 9:29 UTC (permalink / raw)
To: netdev-owner
Cc: netdev, remi.denis-courmont, Dinesh Kumar Sharma, Hemant Ramdasi
From: Dinesh Kumar Sharma <dinesh.sharma@stericsson.com>
This provides flexibility to set the pipe handle
using setsockopt. The pipe can be enabled (if disabled) later
using ioctl.
Signed-off-by: Hemant Ramdasi <hemant.ramdasi@stericsson.com>
Signed-off-by: Dinesh Kumar Sharma <dinesh.sharma@stericsson.com>
---
include/linux/phonet.h | 2 +
net/phonet/pep.c | 96 ++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 91 insertions(+), 7 deletions(-)
diff --git a/include/linux/phonet.h b/include/linux/phonet.h
index 6fb1384..1847ef9 100644
--- a/include/linux/phonet.h
+++ b/include/linux/phonet.h
@@ -37,6 +37,7 @@
#define PNPIPE_ENCAP 1
#define PNPIPE_IFINDEX 2
#define PNPIPE_HANDLE 3
+#define PNPIPE_INITSTATE 4
#define PNADDR_ANY 0
#define PNADDR_BROADCAST 0xFC
@@ -48,6 +49,7 @@
/* ioctls */
#define SIOCPNGETOBJECT (SIOCPROTOPRIVATE + 0)
+#define SIOCPNENABLEPIPE (SIOCPROTOPRIVATE + 13)
#define SIOCPNADDRESOURCE (SIOCPROTOPRIVATE + 14)
#define SIOCPNDELRESOURCE (SIOCPROTOPRIVATE + 15)
diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index f17fd84..7acd262 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -533,6 +533,29 @@ static int pep_connresp_rcv(struct sock *sk, struct sk_buff *skb)
return pipe_handler_send_created_ind(sk);
}
+static int pep_enableresp_rcv(struct sock *sk, struct sk_buff *skb)
+{
+ struct pnpipehdr *hdr = pnp_hdr(skb);
+
+ if (hdr->error_code != PN_PIPE_NO_ERROR)
+ return -ECONNREFUSED;
+
+ return pep_indicate(sk, PNS_PIPE_ENABLED_IND, 0 /* sub-blocks */,
+ NULL, 0, GFP_ATOMIC);
+
+}
+
+static void pipe_start_flow_control(struct sock *sk)
+{
+ struct pep_sock *pn = pep_sk(sk);
+
+ if (!pn_flow_safe(pn->tx_fc)) {
+ atomic_set(&pn->tx_credits, 1);
+ sk->sk_write_space(sk);
+ }
+ pipe_grant_credits(sk, GFP_ATOMIC);
+}
+
/* Queue an skb to an actively connected sock.
* Socket lock must be held. */
static int pipe_handler_do_rcv(struct sock *sk, struct sk_buff *skb)
@@ -578,13 +601,25 @@ static int pipe_handler_do_rcv(struct sock *sk, struct sk_buff *skb)
sk->sk_state = TCP_CLOSE_WAIT;
break;
}
+ if (pn->init_enable == PN_PIPE_DISABLE)
+ sk->sk_state = TCP_SYN_RECV;
+ else {
+ sk->sk_state = TCP_ESTABLISHED;
+ pipe_start_flow_control(sk);
+ }
+ break;
- sk->sk_state = TCP_ESTABLISHED;
- if (!pn_flow_safe(pn->tx_fc)) {
- atomic_set(&pn->tx_credits, 1);
- sk->sk_write_space(sk);
+ case PNS_PEP_ENABLE_RESP:
+ if (sk->sk_state != TCP_SYN_SENT)
+ break;
+
+ if (pep_enableresp_rcv(sk, skb)) {
+ sk->sk_state = TCP_CLOSE_WAIT;
+ break;
}
- pipe_grant_credits(sk, GFP_ATOMIC);
+
+ sk->sk_state = TCP_ESTABLISHED;
+ pipe_start_flow_control(sk);
break;
case PNS_PEP_DISCONNECT_RESP:
@@ -863,14 +898,32 @@ static int pep_sock_connect(struct sock *sk, struct sockaddr *addr, int len)
int err;
u8 data[4] = { 0 /* sub-blocks */, PAD, PAD, PAD };
- pn->pipe_handle = 1; /* anything but INVALID_HANDLE */
+ if (pn->pipe_handle == PN_PIPE_INVALID_HANDLE)
+ pn->pipe_handle = 1; /* anything but INVALID_HANDLE */
+
err = pipe_handler_request(sk, PNS_PEP_CONNECT_REQ,
- PN_PIPE_ENABLE, data, 4);
+ pn->init_enable, data, 4);
if (err) {
pn->pipe_handle = PN_PIPE_INVALID_HANDLE;
return err;
}
+
sk->sk_state = TCP_SYN_SENT;
+
+ return 0;
+}
+
+static int pep_sock_enable(struct sock *sk, struct sockaddr *addr, int len)
+{
+ int err;
+
+ err = pipe_handler_request(sk, PNS_PEP_ENABLE_REQ, PAD,
+ NULL, 0);
+ if (err)
+ return err;
+
+ sk->sk_state = TCP_SYN_SENT;
+
return 0;
}
@@ -894,6 +947,19 @@ static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg)
answ = 0;
release_sock(sk);
return put_user(answ, (int __user *)arg);
+ break;
+
+ case SIOCPNENABLEPIPE:
+ lock_sock(sk);
+ if (sk->sk_state == TCP_SYN_SENT)
+ answ = -EBUSY;
+ else if (sk->sk_state == TCP_ESTABLISHED)
+ answ = -EISCONN;
+ else
+ answ = pep_sock_enable(sk, NULL, 0);
+ release_sock(sk);
+ return answ;
+ break;
}
return -ENOIOCTLCMD;
@@ -959,6 +1025,18 @@ static int pep_setsockopt(struct sock *sk, int level, int optname,
}
goto out_norel;
+ case PNPIPE_HANDLE:
+ if ((sk->sk_state == TCP_CLOSE) &&
+ (val >= 0) && (val < PN_PIPE_INVALID_HANDLE))
+ pn->pipe_handle = val;
+ else
+ err = -EINVAL;
+ break;
+
+ case PNPIPE_INITSTATE:
+ pn->init_enable = !!val;
+ break;
+
default:
err = -ENOPROTOOPT;
}
@@ -994,6 +1072,10 @@ static int pep_getsockopt(struct sock *sk, int level, int optname,
return -EINVAL;
break;
+ case PNPIPE_INITSTATE:
+ val = pn->init_enable;
+ break;
+
default:
return -ENOPROTOOPT;
}
--
1.7.4.3
^ permalink raw reply related
* Re: [PATCH 1/1] net/cadence: enable by default NET_ATMEL
From: Nicolas Ferre @ 2011-11-17 8:56 UTC (permalink / raw)
To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: linux-kernel, netdev
In-Reply-To: <1321385790-15056-1-git-send-email-plagnioj@jcrosoft.com>
On 11/15/2011 08:36 PM, Jean-Christophe PLAGNIOL-VILLARD :
> so the defconfig of the atmel continue to have the support of the network
> as before
>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> ---
> Hi David,
>
> can we have this for the 3.2 so the atmel continue to work as before
>
> Best Regards,
> J.
> drivers/net/ethernet/cadence/Kconfig | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig
> index 98849a1..b48378a 100644
> --- a/drivers/net/ethernet/cadence/Kconfig
> +++ b/drivers/net/ethernet/cadence/Kconfig
> @@ -7,6 +7,7 @@ config HAVE_NET_MACB
>
> config NET_ATMEL
> bool "Atmel devices"
> + default y
> depends on HAVE_NET_MACB || (ARM && ARCH_AT91RM9200)
> ---help---
> If you have a network (Ethernet) card belonging to this class, say Y.
--
Nicolas Ferre
^ permalink raw reply
* Re: [PATCH 1/6] sky2: fix hang on shutdown (and other irq issues)
From: Sven Joachim @ 2011-11-17 8:46 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: davem, netdev
In-Reply-To: <20111116234344.526517614@vyatta.com>
On 2011-11-17 00:42 +0100, Stephen Hemminger wrote:
> There are several problems with recent change to how IRQ's are setup.
> * synchronize_irq in sky2_shutdown would hang because there
> was no IRQ setup.
> * when device was set to down, some IRQ bits left enabled so a
> hardware error would produce IRQ with no handler
> * quick link on Optima chip set was enabled without handler
> * suspend/resume would leave IRQ on with no handler if device
> was down
Unfortunately, this patch does not fix the hang at shutdown for me. :-(
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>
> ---
> This needs to be applied to net-next and -net
>
> --- a/drivers/net/ethernet/marvell/sky2.c 2011-11-16 15:15:48.212513321 -0800
> +++ b/drivers/net/ethernet/marvell/sky2.c 2011-11-16 15:19:32.898508932 -0800
> @@ -1747,6 +1747,11 @@ static int sky2_up(struct net_device *de
>
> sky2_hw_up(sky2);
>
> + if (hw->chip_id == CHIP_ID_YUKON_OPT ||
> + hw->chip_id == CHIP_ID_YUKON_PRM ||
> + hw->chip_id == CHIP_ID_YUKON_OP_2)
> + imask |= Y2_IS_PHY_QLNK; /* enable PHY Quick Link */
> +
> /* Enable interrupts from phy/mac for port */
> imask = sky2_read32(hw, B0_IMSK);
> imask |= portirq_msk[port];
> @@ -2101,15 +2106,21 @@ static int sky2_down(struct net_device *
>
> netif_info(sky2, ifdown, dev, "disabling interface\n");
>
> - /* Disable port IRQ */
> - sky2_write32(hw, B0_IMSK,
> - sky2_read32(hw, B0_IMSK) & ~portirq_msk[sky2->port]);
> - sky2_read32(hw, B0_IMSK);
> -
> if (hw->ports == 1) {
> + sky2_write32(hw, B0_IMSK, 0);
> + sky2_read32(hw, B0_IMSK);
> +
> napi_disable(&hw->napi);
> free_irq(hw->pdev->irq, hw);
> } else {
> + u32 imask;
> +
> + /* Disable port IRQ */
> + imask = sky2_read32(hw, B0_IMSK);
> + imask &= ~portirq_msk[sky2->port];
> + sky2_write32(hw, B0_IMSK, imask);
> + sky2_read32(hw, B0_IMSK);
> +
> synchronize_irq(hw->pdev->irq);
> napi_synchronize(&hw->napi);
> }
> @@ -3258,7 +3269,6 @@ static void sky2_reset(struct sky2_hw *h
> hw->chip_id == CHIP_ID_YUKON_PRM ||
> hw->chip_id == CHIP_ID_YUKON_OP_2) {
> u16 reg;
> - u32 msk;
>
> if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {
> /* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */
> @@ -3281,11 +3291,6 @@ static void sky2_reset(struct sky2_hw *h
> sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
> sky2_pci_write16(hw, PSM_CONFIG_REG4, reg);
>
> - /* enable PHY Quick Link */
> - msk = sky2_read32(hw, B0_IMSK);
> - msk |= Y2_IS_PHY_QLNK;
> - sky2_write32(hw, B0_IMSK, msk);
> -
> /* check if PSMv2 was running before */
> reg = sky2_pci_read16(hw, PSM_CONFIG_REG3);
> if (reg & PCI_EXP_LNKCTL_ASPMC)
> @@ -3412,7 +3417,9 @@ static void sky2_all_down(struct sky2_hw
>
> sky2_read32(hw, B0_IMSK);
> sky2_write32(hw, B0_IMSK, 0);
> - synchronize_irq(hw->pdev->irq);
> +
> + if (hw->ports > 1 || netif_running(hw->dev[0]))
> + synchronize_irq(hw->pdev->irq);
> napi_disable(&hw->napi);
>
> for (i = 0; i < hw->ports; i++) {
> @@ -3430,7 +3437,7 @@ static void sky2_all_down(struct sky2_hw
>
> static void sky2_all_up(struct sky2_hw *hw)
> {
> - u32 imask = Y2_IS_BASE;
> + u32 imask = 0;
> int i;
>
> for (i = 0; i < hw->ports; i++) {
> @@ -3446,11 +3453,13 @@ static void sky2_all_up(struct sky2_hw *
> netif_wake_queue(dev);
> }
>
> - sky2_write32(hw, B0_IMSK, imask);
> - sky2_read32(hw, B0_IMSK);
> -
> - sky2_read32(hw, B0_Y2_SP_LISR);
> - napi_enable(&hw->napi);
> + if (imask || hw->ports > 1) {
> + imask |= Y2_IS_BASE;
> + sky2_write32(hw, B0_IMSK, imask);
> + sky2_read32(hw, B0_IMSK);
> + sky2_read32(hw, B0_Y2_SP_LISR);
> + napi_enable(&hw->napi);
> + }
> }
>
> static void sky2_restart(struct work_struct *work)
^ permalink raw reply
* [PATCH] ipv4: avoid to double release dst in tcp_v4_connect
From: roy.qing.li @ 2011-11-17 8:33 UTC (permalink / raw)
To: netdev
From: RongQing.Li <roy.qing.li@gmail.com>
When tcp_connect failed in tcp_v4_connect, the dst will be
released in error handler of tcp_v4_connect, but dst has been
set to sk->sk_dst_cache which will be released again when
destroy this sk.
Signed-off-by: RongQing.Li <roy.qing.li@gmail.com>
---
net/ipv4/tcp_ipv4.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index a744315..adc2992 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -263,8 +263,10 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
err = tcp_connect(sk);
rt = NULL;
- if (err)
+ if (err) {
+ sk->sk_dst_cache = NULL;
goto failure;
+ }
return 0;
--
1.7.1
^ permalink raw reply related
* Re: [patch net-next 3/3] team: replicate options on register
From: Eric Dumazet @ 2011-11-17 8:32 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, bhutchings, shemminger, andy, fbl, jzupka, ivecera
In-Reply-To: <1321477749-1877-4-git-send-email-jpirko@redhat.com>
Le mercredi 16 novembre 2011 à 22:09 +0100, Jiri Pirko a écrit :
> +
> +int team_options_register(struct team *team,
> + const struct team_option *option,
> + size_t option_count)
> {
> int i;
> + struct team_option *dst_opts[option_count];
> + int err;
This kind of construct will trigger static analyzer alerts...
^ permalink raw reply
* Re: [PATCH net-next] IPV6 Fix a crash when trying to replace non existing route
From: David Miller @ 2011-11-17 8:19 UTC (permalink / raw)
To: matti.vaittinen; +Cc: netdev
In-Reply-To: <1321514282.1858.125.camel@hakki>
From: Matti Vaittinen <matti.vaittinen@nsn.com>
Date: Thu, 17 Nov 2011 09:18:02 +0200
>
> This patch fixes a crash when non existing IPv6 route is tried to be changed.
>
> When new destination node was inserted in middle of FIB6 tree, no relevant
> sanity checks were performed. Later route insertion might have been prevented
> due to invalid request, causing node with no rt info being left in tree.
> When this node was accessed, a crash occurred.
>
> Patch adds missing checks in fib6_add_1()
>
> Signed-off-by: Matti Vaittinen <Mazziesaccount@gmail.com>
Applied.
I also added the following patch, I should have caught this in your
original submission.
--------------------
[PATCH] ipv6: Use pr_warn() in ip6_fib.c
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/ipv6/ip6_fib.c | 20 ++++++++++----------
1 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index e7b26dc..424f063 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -451,12 +451,12 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr,
!ipv6_prefix_equal(&key->addr, addr, fn->fn_bit)) {
if (!allow_create) {
if (replace_required) {
- printk(KERN_WARNING
- "IPv6: Can't replace route, no match found\n");
+ pr_warn("IPv6: Can't replace route, "
+ "no match found\n");
return ERR_PTR(-ENOENT);
}
- printk(KERN_WARNING
- "IPv6: NLM_F_CREATE should be set when creating new route\n");
+ pr_warn("IPv6: NLM_F_CREATE should be set "
+ "when creating new route\n");
}
goto insert_above;
}
@@ -499,11 +499,11 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr,
* That would keep IPv6 consistent with IPv4
*/
if (replace_required) {
- printk(KERN_WARNING
- "IPv6: Can't replace route, no match found\n");
+ pr_warn("IPv6: Can't replace route, no match found\n");
return ERR_PTR(-ENOENT);
}
- printk(KERN_WARNING "IPv6: NLM_F_CREATE should be set when creating new route\n");
+ pr_warn("IPv6: NLM_F_CREATE should be set "
+ "when creating new route\n");
}
/*
* We walked to the bottom of tree.
@@ -697,7 +697,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
*/
if (!replace) {
if (!add)
- printk(KERN_WARNING "IPv6: NLM_F_CREATE should be set when creating new route\n");
+ pr_warn("IPv6: NLM_F_CREATE should be set when creating new route\n");
add:
rt->dst.rt6_next = iter;
@@ -716,7 +716,7 @@ add:
if (!found) {
if (add)
goto add;
- printk(KERN_WARNING "IPv6: NLM_F_REPLACE set, but no existing node found!\n");
+ pr_warn("IPv6: NLM_F_REPLACE set, but no existing node found!\n");
return -ENOENT;
}
*ins = rt;
@@ -768,7 +768,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info)
replace_required = 1;
}
if (!allow_create && !replace_required)
- printk(KERN_WARNING "IPv6: RTM_NEWROUTE with no NLM_F_CREATE or NLM_F_REPLACE\n");
+ pr_warn("IPv6: RTM_NEWROUTE with no NLM_F_CREATE or NLM_F_REPLACE\n");
fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr),
rt->rt6i_dst.plen, offsetof(struct rt6_info, rt6i_dst),
--
1.7.6.4
^ permalink raw reply related
* Re: [PATCH 5/5] stmmac: fix pm functions avoiding sleep on spinlock
From: David Miller @ 2011-11-17 8:14 UTC (permalink / raw)
To: peppe.cavallaro; +Cc: netdev, francesco.virlinzi, srinivas.kandagatla
In-Reply-To: <1321516682-32208-5-git-send-email-peppe.cavallaro@st.com>
From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
Date: Thu, 17 Nov 2011 08:58:02 +0100
> From: Francesco Virlinzi <francesco.virlinzi@st.com>
>
> This patch fixes the pm functions to avoid the system
> sleeps while a spinlock is taken.
>
> Signed-off-by: Francesco Virlinzi <francesco.virlinzi@st.com>
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Applied.
^ 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