Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 13/36] drivers/net/caif: Remove unnecessary casts of private_data
From: David Miller @ 2010-07-13  4:13 UTC (permalink / raw)
  To: joe; +Cc: trivial, linux-kernel, netdev
In-Reply-To: <2fadd3261e91b96050bf8193efacee08842ef9eb.1278967120.git.joe@perches.com>

From: Joe Perches <joe@perches.com>
Date: Mon, 12 Jul 2010 13:50:05 -0700

> Signed-off-by: Joe Perches <joe@perches.com>

Applied.

^ permalink raw reply

* Re: [PATCH 32/36] net/irda: Remove unnecessary casts of private_data
From: David Miller @ 2010-07-13  4:14 UTC (permalink / raw)
  To: joe; +Cc: trivial, linux-kernel, samuel, netdev
In-Reply-To: <0f791bb0d02971908720f0d09b4d8ff9140bb6d0.1278967121.git.joe@perches.com>

From: Joe Perches <joe@perches.com>
Date: Mon, 12 Jul 2010 13:50:24 -0700

> Signed-off-by: Joe Perches <joe@perches.com>

Applied.

^ permalink raw reply

* Re: [REGRESSION,BISECTED] Panic on ifup
From: David Miller @ 2010-07-13  4:20 UTC (permalink / raw)
  To: timo.teras; +Cc: linux, netdev
In-Reply-To: <4C3ABDC3.3000408@iki.fi>

From: Timo Teräs <timo.teras@iki.fi>
Date: Mon, 12 Jul 2010 10:01:23 +0300

> And here goes the patch (which I've only compile tested so far).

Timo, since this tested positively for the reporter, please make
a formal submission once you are happy with the patch.

Thanks.

^ permalink raw reply

* Re: [PATCH] hso: remove driver version
From: David Miller @ 2010-07-13  4:21 UTC (permalink / raw)
  To: f.aben; +Cc: gregkh, linux-usb, netdev
In-Reply-To: <1278942125.23105.39.camel@filip-linux>

From: Filip Aben <f.aben@option.com>
Date: Mon, 12 Jul 2010 15:42:05 +0200

> This patch removes the driver version from the driver. This version
> hasn't changed since the driver's inclusion in the kernel and is a
> source of confusion for some customers.
> 
> Signed-off-by: Filip Aben <f.aben@option.com>

Applied, thanks.

^ permalink raw reply

* iproute, batch-cmds, and mac-vlans.
From: Ben Greear @ 2010-07-13  4:49 UTC (permalink / raw)
  To: NetDev

After too much time debugging, I finally realized that the ip
tool was truncating my command because the mac-vlan device name
had a '#' in it.

]# cat /tmp/foo.txt
ru add to 10.99.21.1 iif eth0#0 lookup local pref 11


# IP tool has some hacked up debugging code
]# ip -batch /tmp/foo.txt
  argc: 4
  arg -:to:-
  arg -:iif:-
WARNING:  Using TABLE_MAIN in iprule_modify, table_ok: 0  cmd: 32


So, it acts on eth0 instead of eth0#0, and silently ignores the 'lookup local pref 11'.

I understand that it is trying to parse # as comments, but would you
all be interested in a patch that allowed ignoring '#' except
when it is the first non-whitespace character on a line, and maybe
when preceded by whitespace?  This would of course have the possibility
of breaking someone's script somewhere, so it could be enabled with
a new command line arg, perhaps.

Thanks,
Ben

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com

^ permalink raw reply

* Re: [Pv-drivers] RFC: Network Plugin Architecture (NPA) for vmxnet3
From: Stephen Hemminger @ 2010-07-13  5:16 UTC (permalink / raw)
  To: Shreyas Bhatewara
  Cc: Christoph Hellwig, Pankaj Thakkar, pv-drivers@vmware.com,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	virtualization@lists.linux-foundation.org
In-Reply-To: <1278990388.32650.22.camel@eng-rhel5-64>

On Mon, 12 Jul 2010 20:06:28 -0700
Shreyas Bhatewara <sbhatewara@vmware.com> wrote:

> 
> On Thu, 2010-05-06 at 13:21 -0700, Christoph Hellwig wrote:
> > On Wed, May 05, 2010 at 10:52:53AM -0700, Stephen Hemminger wrote:
> > > Let me put it bluntly. Any design that allows external code to run
> > > in the kernel is not going to be accepted.  Out of tree kernel modules are enough
> > > of a pain already, why do you expect the developers to add another
> > > interface.
> > 
> > Exactly.  Until our friends at VMware get this basic fact it's useless
> > to continue arguing.
> > 
> > Pankaj and Dmitry: you're fine to waste your time on this, but it's not
> > going to go anywhere until you address that fundamental problem.  The
> > first thing you need to fix in your archicture is to integrate the VF
> > function code into the kernel tree, and we can work from there.
> > 
> > Please post patches doing this if you want to resume the discussion.
> > 
> > _______________________________________________
> > Pv-drivers mailing list
> > Pv-drivers@vmware.com
> > http://mailman2.vmware.com/mailman/listinfo/pv-drivers
> 
> 
> As discussed, following is the patch to give you an idea
> about implementation of NPA for vmxnet3 driver. Although the
> patch is big, I have verified it with checkpatch.pl. It gave
> 0 errors / warnings.
> 
> Signed-off-by: Matthieu Bucchaineri <matthieu@vmware.com>
> Signed-off-by: Shreyas Bhatewara <sbhatewara@vmware.com>

I think the concept won't fly.

But you should really at least try running checkpatch to make sure
the style conforms.


-- 

^ permalink raw reply

* Re: iproute, batch-cmds, and mac-vlans.
From: Stephen Hemminger @ 2010-07-13  5:19 UTC (permalink / raw)
  To: Ben Greear; +Cc: NetDev
In-Reply-To: <4C3BF050.7040206@candelatech.com>

On Mon, 12 Jul 2010 21:49:20 -0700
Ben Greear <greearb@candelatech.com> wrote:

> After too much time debugging, I finally realized that the ip
> tool was truncating my command because the mac-vlan device name
> had a '#' in it.
> 
> ]# cat /tmp/foo.txt
> ru add to 10.99.21.1 iif eth0#0 lookup local pref 11
> 
> 
> # IP tool has some hacked up debugging code
> ]# ip -batch /tmp/foo.txt
>   argc: 4
>   arg -:to:-
>   arg -:iif:-
> WARNING:  Using TABLE_MAIN in iprule_modify, table_ok: 0  cmd: 32
> 
> 
> So, it acts on eth0 instead of eth0#0, and silently ignores the 'lookup local pref 11'.
> 
> I understand that it is trying to parse # as comments, but would you
> all be interested in a patch that allowed ignoring '#' except
> when it is the first non-whitespace character on a line, and maybe
> when preceded by whitespace?  This would of course have the possibility
> of breaking someone's script somewhere, so it could be enabled with
> a new command line arg, perhaps.

Putting # in device name just sounds like a bad idea.

^ permalink raw reply

* Re: iproute, batch-cmds, and mac-vlans.
From: Ben Greear @ 2010-07-13  5:32 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: NetDev
In-Reply-To: <20100712221958.2a87b0e3@nehalam>

On 07/12/2010 10:19 PM, Stephen Hemminger wrote:
> On Mon, 12 Jul 2010 21:49:20 -0700
> Ben Greear<greearb@candelatech.com>  wrote:
>
>> After too much time debugging, I finally realized that the ip
>> tool was truncating my command because the mac-vlan device name
>> had a '#' in it.
>>
>> ]# cat /tmp/foo.txt
>> ru add to 10.99.21.1 iif eth0#0 lookup local pref 11
>>
>>
>> # IP tool has some hacked up debugging code
>> ]# ip -batch /tmp/foo.txt
>>    argc: 4
>>    arg -:to:-
>>    arg -:iif:-
>> WARNING:  Using TABLE_MAIN in iprule_modify, table_ok: 0  cmd: 32
>>
>>
>> So, it acts on eth0 instead of eth0#0, and silently ignores the 'lookup local pref 11'.
>>
>> I understand that it is trying to parse # as comments, but would you
>> all be interested in a patch that allowed ignoring '#' except
>> when it is the first non-whitespace character on a line, and maybe
>> when preceded by whitespace?  This would of course have the possibility
>> of breaking someone's script somewhere, so it could be enabled with
>> a new command line arg, perhaps.
>
> Putting # in device name just sounds like a bad idea.

It's been the standard naming for mac-vlans since we started supporting them.

In case you change your mind, this patch seems to work..though I can't figure out
how to trigger the second bit of code in the while loop, so it may not be right.

I'll move my iproute2 tree to github in case someone else wants to give
it a try.

diff --git a/lib/utils.c b/lib/utils.c
index a60d884..ad8e1ac 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -25,7 +25,7 @@
  #include <linux/pkt_sched.h>
  #include <time.h>
  #include <sys/time.h>
-
+#include <ctype.h>

  #include "utils.h"

@@ -708,8 +708,23 @@ ssize_t getcmdline(char **linep, size_t *lenp, FILE *in)
         ++cmdlineno;

         cp = strchr(*linep, '#');
-       if (cp)
-               *cp = '\0';
+
+       /* We don't want to treat the # in the middle of a word as
+        * a comment..makes batch commands dealing with mac-vlans: eth0#1
+        * silently do the wrong thing.  So, tighten up the # syntax a bit.
+        *
+        * # at start of line comments rest of line
+        * # preceded by a whitespace character comments rest of line.
+        */
+       while (cp) {
+               if (cp &&
+                   ((cp == *linep) /* starts line */
+                    || ((cp > *linep) && isspace(*(cp - 1))))) { /* follows space */
+                       *cp = '\0';
+                       break;
+               }
+               cp = strchr(cp+1, '#');
+       }

         while ((cp = strstr(*linep, "\\\n")) != NULL) {
                 char *line1 = NULL;
@@ -725,9 +740,16 @@ ssize_t getcmdline(char **linep, size_t *lenp, FILE *in)
                 *cp = 0;

                 cp = strchr(line1, '#');
-               if (cp)
-                       *cp = '\0';
-
+               while (cp) {
+                       if (cp &&
+                           ((cp == line1) /* starts line */
+                            || ((cp > line1) && isspace(*(cp - 1))))) { /* follows space */
+                               *cp = '\0';
+                               break;
+                       }
+                       cp = strchr(cp+1, '#');
+               }
+
                 *lenp = strlen(*linep) + strlen(line1) + 1;
                 *linep = realloc(*linep, *lenp);
                 if (!*linep) {

> --
> 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


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com

^ permalink raw reply related

* Re: [PATCH] netfilter: xtables: userspace notification target
From: Jan Engelhardt @ 2010-07-13  5:56 UTC (permalink / raw)
  To: Samuel Ortiz
  Cc: Patrick McHardy, David S. Miller, netdev, netfilter-devel,
	Luciano Coelho
In-Reply-To: <20100713001115.GA3751@sortiz-mobl>


On Tuesday 2010-07-13 02:11, Samuel Ortiz wrote:
>
>The userspace notification Xtables target sends a netlink notification
>whenever a packet hits the target. Notifications have a label attribute
>for userspace to match it against a previously set rule. The rules also
>take a --all option to switch between sending a notification for all
>packets or for the first one only.
>Userspace can also send a netlink message to toggle this switch while the
>target is in place. This target uses the nefilter netlink framework.

Would it not make sense to modify that module?
Sounds an awful lot like NFQUEUE without passing the payload :)

>+++ b/net/netfilter/xt_NFNOTIF.c
>+struct nfnotif_tg {
>+	struct list_head entry;
>+	struct work_struct work;
>+
>+	char *label;
>+	__u8 all_packets;
>+	struct net *net;
>+
>+	__u8 send_notif;
>+
>+	unsigned int refcnt;
>+};

Has unnecessary padding holes.

^ permalink raw reply

* Re: [PATCH] netfilter: xtables: userspace notification target
From: Changli Gao @ 2010-07-13  6:18 UTC (permalink / raw)
  To: Samuel Ortiz
  Cc: Patrick McHardy, David S. Miller, netdev, netfilter-devel,
	Luciano Coelho
In-Reply-To: <20100713001115.GA3751@sortiz-mobl>

On Tue, Jul 13, 2010 at 8:11 AM, Samuel Ortiz <sameo@linux.intel.com> wrote:
>
> The userspace notification Xtables target sends a netlink notification
> whenever a packet hits the target. Notifications have a label attribute
> for userspace to match it against a previously set rule. The rules also
> take a --all option to switch between sending a notification for all
> packets or for the first one only.
> Userspace can also send a netlink message to toggle this switch while the
> target is in place. This target uses the nefilter netlink framework.
>
> This target combined with various matches (quota, rateest, etc..) allows
> userspace to make decisions on interfaces handling. One could for example
> decide to switch between power saving modes depending on estimated rate
> thresholds.
>

It much like the following iptables rules.

iptables -N log_and_drop
iptables -A log_and_drop -j NFLOG --nflog-group 1 --nflog-prefix "log_and_drop"
iptables -A log_and_drop -j DROP

...
iptables ... -m quota --quota-bytes 20000 -j log_and_drop
...

>  include/linux/netfilter/Kbuild             |    1 +
>  include/linux/netfilter/nfnetlink.h        |    5 +-
>  include/linux/netfilter/nfnetlink_compat.h |    1 +
>  include/linux/netfilter/xt_NFNOTIF.h       |   55 +++++
>  net/netfilter/Kconfig                      |   17 ++
>  net/netfilter/Makefile                     |    1 +
>  net/netfilter/xt_NFNOTIF.c                 |  300 ++++++++++++++++++++++++++++
>  7 files changed, 379 insertions(+), 1 deletions(-)
>  create mode 100644 include/linux/netfilter/xt_NFNOTIF.h
>  create mode 100644 net/netfilter/xt_NFNOTIF.c
>
> diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
> index bb103f4..1b80b27 100644
> --- a/include/linux/netfilter/Kbuild
> +++ b/include/linux/netfilter/Kbuild
> @@ -12,6 +12,7 @@ header-y += xt_IDLETIMER.h
>  header-y += xt_LED.h
>  header-y += xt_MARK.h
>  header-y += xt_NFLOG.h
> +header-y += xt_NFNOTIF.h
>  header-y += xt_NFQUEUE.h
>  header-y += xt_RATEEST.h
>  header-y += xt_SECMARK.h
> diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
> index 361d6b5..e336f03 100644
> --- a/include/linux/netfilter/nfnetlink.h
> +++ b/include/linux/netfilter/nfnetlink.h
> @@ -18,6 +18,8 @@ enum nfnetlink_groups {
>  #define NFNLGRP_CONNTRACK_EXP_UPDATE   NFNLGRP_CONNTRACK_EXP_UPDATE
>        NFNLGRP_CONNTRACK_EXP_DESTROY,
>  #define NFNLGRP_CONNTRACK_EXP_DESTROY  NFNLGRP_CONNTRACK_EXP_DESTROY
> +       NFNLGRP_NFNOTIF,
> +#define NFNLGRP_NFNOTIF                        NFNLGRP_NFNOTIF
>        __NFNLGRP_MAX,
>  };
>  #define NFNLGRP_MAX    (__NFNLGRP_MAX - 1)
> @@ -47,7 +49,8 @@ struct nfgenmsg {
>  #define NFNL_SUBSYS_QUEUE              3
>  #define NFNL_SUBSYS_ULOG               4
>  #define NFNL_SUBSYS_OSF                        5
> -#define NFNL_SUBSYS_COUNT              6
> +#define NFNL_SUBSYS_NFNOTIF            6
> +#define NFNL_SUBSYS_COUNT              7
>
>  #ifdef __KERNEL__
>
> diff --git a/include/linux/netfilter/nfnetlink_compat.h b/include/linux/netfilter/nfnetlink_compat.h
> index ffb9503..dca8ab2 100644
> --- a/include/linux/netfilter/nfnetlink_compat.h
> +++ b/include/linux/netfilter/nfnetlink_compat.h
> @@ -13,6 +13,7 @@
>  #define NF_NETLINK_CONNTRACK_EXP_NEW           0x00000008
>  #define NF_NETLINK_CONNTRACK_EXP_UPDATE                0x00000010
>  #define NF_NETLINK_CONNTRACK_EXP_DESTROY       0x00000020
> +#define NF_NETLINK_NFNOTIF                     0x00000040
>
>  /* Generic structure for encapsulation optional netfilter information.
>  * It is reminiscent of sockaddr, but with sa_family replaced
> diff --git a/include/linux/netfilter/xt_NFNOTIF.h b/include/linux/netfilter/xt_NFNOTIF.h
> new file mode 100644
> index 0000000..8fae827
> --- /dev/null
> +++ b/include/linux/netfilter/xt_NFNOTIF.h
> @@ -0,0 +1,55 @@
> +/*
> + * linux/include/linux/netfilter/xt_NFNOTIF.h
> + *
> + * Header file for Xtables notification target module.
> + *
> + * Copyright (C) 2010 Intel Corporation
> + * Samuel Ortiz <samuel.ortiz@intel.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + */
> +
> +#ifndef _XT_NFNOTIF_H
> +#define _XT_NFNOTIF_H
> +
> +#include <linux/types.h>
> +
> +enum nfnotif_msg_type {
> +       NFNOTIF_TG_MSG_PACKETS,
> +
> +       NFNOTIF_TG_MSG_MAX
> +};
> +
> +enum nfnotif_attr_type {
> +       NFNOTIF_TG_ATTR_UNSPEC,
> +       NFNOTIF_TG_ATTR_LABEL,
> +       NFNOTIF_TG_ATTR_SEND_NOTIF,
> +
> +       __NFNOTIF_TG_ATTR_AFTER_LAST
> +};
> +#define NFNOTIF_TG_ATTR_MAX (__NFNOTIF_TG_ATTR_AFTER_LAST - 1)
> +
> +#define MAX_NFNOTIF_LABEL_SIZE 31
> +
> +struct nfnotif_tg_info {
> +       __u8 all_packets;
> +
> +       char label[MAX_NFNOTIF_LABEL_SIZE];
> +
> +       /* for kernel module internal use only */
> +       struct nfnotif_tg *notif __attribute((aligned(8)));
> +};
> +
> +#endif
> diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
> index aa2f106..0e2de36 100644
> --- a/net/netfilter/Kconfig
> +++ b/net/netfilter/Kconfig
> @@ -469,6 +469,23 @@ config NETFILTER_XT_TARGET_NFQUEUE
>
>          To compile it as a module, choose M here.  If unsure, say N.
>
> +config NETFILTER_XT_TARGET_NFNOTIF
> +       tristate '"NFNOTIF" target Support'
> +       depends on NETFILTER_ADVANCED
> +       select NETFILTER_NETLINK
> +       help
> +
> +         This option adds the `NFNOTIF' target, which allows to send
> +         netfilter netlink messages when packets hit the target.
> +
> +         This target comes with an option to specify if one wants all
> +         packets hitting the target to trigger the netlink message
> +         transmission, or only the first one.
> +         It also listen on its netfilter netlink subsystem for messages
> +         allowing to reset the above option.
> +
> +         To compile it as a module, choose M here.  If unsure, say N.
> +
>  config NETFILTER_XT_TARGET_NOTRACK
>        tristate  '"NOTRACK" target support'
>        depends on IP_NF_RAW || IP6_NF_RAW
> diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
> index e28420a..5d9c9e9 100644
> --- a/net/netfilter/Makefile
> +++ b/net/netfilter/Makefile
> @@ -62,6 +62,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
>  obj-$(CONFIG_NETFILTER_XT_TARGET_TEE) += xt_TEE.o
>  obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
>  obj-$(CONFIG_NETFILTER_XT_TARGET_IDLETIMER) += xt_IDLETIMER.o
> +obj-$(CONFIG_NETFILTER_XT_TARGET_NFNOTIF) += xt_NFNOTIF.o
>
>  # matches
>  obj-$(CONFIG_NETFILTER_XT_MATCH_CLUSTER) += xt_cluster.o
> diff --git a/net/netfilter/xt_NFNOTIF.c b/net/netfilter/xt_NFNOTIF.c
> new file mode 100644
> index 0000000..e6e906b
> --- /dev/null
> +++ b/net/netfilter/xt_NFNOTIF.c
> @@ -0,0 +1,300 @@
> +/*
> + * linux/net/netfilter/xt_NFNOTIF.c
> + *
> + * Copyright (C) 2010 Intel Corporation
> + * Samuel Ortiz <samuel.ortiz@intel.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + *
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include <linux/module.h>
> +#include <linux/list.h>
> +#include <linux/mutex.h>
> +#include <linux/netfilter.h>
> +#include <linux/netfilter/x_tables.h>
> +#include <linux/netfilter/nfnetlink.h>
> +#include <linux/netfilter/xt_NFNOTIF.h>
> +
> +struct nfnotif_tg {
> +       struct list_head entry;
> +       struct work_struct work;
> +
> +       char *label;
> +       __u8 all_packets;
> +       struct net *net;
> +
> +       __u8 send_notif;
> +
> +       unsigned int refcnt;
> +};
> +
> +static LIST_HEAD(nfnotif_tg_list);
> +static DEFINE_MUTEX(list_mutex);
> +
> +static int __nfnotif_tg_netlink_send(struct nfnotif_tg *nfnotif)
> +{
> +       struct nlmsghdr *nlh;
> +       struct nfgenmsg *nfmsg;
> +       struct sk_buff *skb;
> +       struct net *net = nfnotif->net;
> +       unsigned int type;
> +       int flags;
> +
> +       type = NFNL_SUBSYS_NFNOTIF << 8;
> +       flags = NLM_F_CREATE;
> +
> +       skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
> +       if (skb == NULL)
> +               goto error_out;
> +
> +       nlh = nlmsg_put(skb, 0, 0, type, sizeof(*nfmsg), flags);
> +       if (nlh == NULL)
> +               goto nlmsg_put_failure;
> +
> +       nfmsg = nlmsg_data(nlh);
> +       nfmsg->version      = NFNETLINK_V0;
> +       nfmsg->res_id       = 0;
> +
> +       NLA_PUT_STRING(skb, NFNOTIF_TG_ATTR_LABEL, nfnotif->label);
> +
> +       nlmsg_end(skb, nlh);
> +
> +       return nfnetlink_send(skb, net, 0, NFNLGRP_NFNOTIF, 0, GFP_KERNEL);
> +
> +nla_put_failure:
> +       nlmsg_cancel(skb, nlh);
> +
> +nlmsg_put_failure:
> +       kfree_skb(skb);
> +
> +error_out:
> +       return nfnetlink_set_err(net, 0, 0, -ENOBUFS);
> +}
> +
> +static void nfnotif_tg_work(struct work_struct *work)
> +{
> +       struct nfnotif_tg *notif = container_of(work, struct nfnotif_tg, work);
> +
> +
> +       if (__nfnotif_tg_netlink_send(notif) < 0)
> +               pr_debug("Could not send notification");
> +
> +       if (!notif->all_packets)
> +               notif->send_notif = 0;
> +}
> +
> +static struct nfnotif_tg *__nfnotif_tg_find_by_label(const char *label)
> +{
> +       struct nfnotif_tg *entry;
> +
> +       BUG_ON(!label);
> +
> +       list_for_each_entry(entry, &nfnotif_tg_list, entry) {
> +               if (!strcmp(label, entry->label))
> +                       return entry;
> +       }
> +
> +       return NULL;
> +}
> +
> +static int nfnotif_tg_create(struct nfnotif_tg_info *info)
> +{
> +       info->notif = kmalloc(sizeof(*info->notif), GFP_KERNEL);
> +       if (!info->notif) {
> +               pr_debug("Couldn't allocate notification\n");
> +               return -ENOMEM;
> +       }
> +
> +       info->notif->label = kstrdup(info->label, GFP_KERNEL);
> +       if (!info->notif->label) {
> +               pr_debug("Couldn't allocate label\n");
> +               kfree(info->notif);
> +               return -ENOMEM;
> +       }
> +
> +       info->notif->all_packets = info->all_packets;
> +       info->notif->send_notif = 1;
> +
> +       list_add(&info->notif->entry, &nfnotif_tg_list);
> +
> +       info->notif->refcnt = 1;
> +
> +       INIT_WORK(&info->notif->work, nfnotif_tg_work);
> +
> +       return 0;
> +}
> +
> +static unsigned int nfnotif_tg_target(struct sk_buff *skb,
> +                                     const struct xt_action_param *par)
> +{
> +       const struct nfnotif_tg_info *info = par->targinfo;
> +
> +       BUG_ON(!info->notif);
> +
> +       if (!info->notif->send_notif)
> +               return XT_CONTINUE;
> +
> +       pr_debug("Sending notification for %s\n", info->label);
> +
> +       schedule_work(&info->notif->work);
> +

Why do you use another kernel activity: kernel thread? netlink
messages can be sent in atomic context.

> +       return XT_CONTINUE;
> +}
> +
> +static int nfnotif_tg_checkentry(const struct xt_tgchk_param *par)
> +{
> +       struct nfnotif_tg_info *info = par->targinfo;
> +       int ret;
> +
> +       pr_debug("Checkentry targinfo %s\n", info->label);
> +
> +       if (info->label[0] == '\0' ||
> +           strnlen(info->label,
> +                   MAX_NFNOTIF_LABEL_SIZE) == MAX_NFNOTIF_LABEL_SIZE) {
> +               pr_debug("Label is empty or not nul-terminated\n");
> +               return -EINVAL;
> +       }
> +
> +       mutex_lock(&list_mutex);
> +
> +       info->notif = __nfnotif_tg_find_by_label(info->label);
> +       if (info->notif) {
> +               info->notif->refcnt++;
> +
> +               pr_debug("Increased refcnt for %s to %u\n",
> +                        info->label, info->notif->refcnt);
> +       } else {
> +               ret = nfnotif_tg_create(info);
> +               if (ret < 0) {
> +                       pr_debug("Failed to create notification\n");
> +                       mutex_unlock(&list_mutex);
> +                       return ret;
> +               }
> +       }
> +
> +       info->notif->net = par->net;
> +
> +       mutex_unlock(&list_mutex);
> +       return 0;
> +}
> +
> +static void nfnotif_tg_destroy(const struct xt_tgdtor_param *par)
> +{
> +       const struct nfnotif_tg_info *info = par->targinfo;
> +
> +       pr_debug("Destroy targinfo %s\n", info->label);
> +
> +       mutex_lock(&list_mutex);
> +
> +       if (--info->notif->refcnt == 0) {
> +               pr_debug("Deleting notification %s\n", info->label);
> +
> +               list_del(&info->notif->entry);
> +               kfree(info->notif->label);
> +               kfree(info->notif);
> +       }
> +
> +       mutex_unlock(&list_mutex);
> +}
> +
> +static struct xt_target nfnotif_tg __read_mostly = {
> +       .name           = "NFNOTIF",
> +       .family         = NFPROTO_UNSPEC,
> +       .target         = nfnotif_tg_target,
> +       .targetsize     = sizeof(struct nfnotif_tg_info),
> +       .checkentry     = nfnotif_tg_checkentry,
> +       .destroy        = nfnotif_tg_destroy,
> +       .me             = THIS_MODULE,
> +};
> +
> +static int nfnotif_msg_send_notif(struct sock *nfnl, struct sk_buff *skb,
> +                                 const struct nlmsghdr *nlh,
> +                                 const struct nlattr * const attrs[])
> +{
> +       struct nfnotif_tg *notif;
> +       char *label;
> +       u8 send_notif;
> +
> +       if (attrs[NFNOTIF_TG_ATTR_LABEL] == NULL ||
> +           attrs[NFNOTIF_TG_ATTR_SEND_NOTIF] == NULL)
> +               return -EINVAL;
> +
> +       label = nla_data(attrs[NFNOTIF_TG_ATTR_LABEL]);
> +       send_notif = nla_get_u8(attrs[NFNOTIF_TG_ATTR_SEND_NOTIF]);
> +
> +       pr_debug("Label %s send %d\n", label, send_notif);
> +
> +       notif = __nfnotif_tg_find_by_label(label);
> +       if (notif == NULL)
> +               return -EINVAL;
> +
> +       notif->send_notif = send_notif;
> +
> +       return 0;
> +}
> +
> +
> +static const struct nla_policy nfnotif_nla_policy[NFNOTIF_TG_ATTR_MAX + 1] = {
> +       [NFNOTIF_TG_ATTR_LABEL]            = { .type = NLA_NUL_STRING },
> +       [NFNOTIF_TG_ATTR_SEND_NOTIF]       = { .type = NLA_U8 },
> +};
> +
> +static const struct nfnl_callback nfnotif_cb[NFNOTIF_TG_MSG_MAX] = {
> +       [NFNOTIF_TG_MSG_PACKETS]   = { .call = nfnotif_msg_send_notif,
> +                                      .attr_count = NFNOTIF_TG_ATTR_MAX,
> +                                      .policy = nfnotif_nla_policy },
> +};
> +
> +static const struct nfnetlink_subsystem nfnotif_subsys = {
> +       .name                           = "nfnotif",
> +       .subsys_id                      = NFNL_SUBSYS_NFNOTIF,
> +       .cb_count                       = NFNOTIF_TG_MSG_MAX,
> +       .cb                             = nfnotif_cb,
> +};
> +
> +static int __init nfnotif_tg_init(void)
> +{
> +       int ret;
> +
> +       ret = nfnetlink_subsys_register(&nfnotif_subsys);
> +       if (ret < 0) {
> +               pr_err("%s: Cannot register with nfnetlink\n", __func__);
> +               return ret;
> +       }
> +
> +       ret = xt_register_target(&nfnotif_tg);
> +       if (ret < 0) {
> +               pr_err("%s: Cannot register target\n", __func__);
> +               nfnetlink_subsys_unregister(&nfnotif_subsys);
> +       }
> +
> +       return ret;
> +}
> +
> +static void __exit nfnotif_tg_exit(void)
> +{
> +       nfnetlink_subsys_unregister(&nfnotif_subsys);
> +       xt_unregister_target(&nfnotif_tg);
> +}
> +
> +module_init(nfnotif_tg_init);
> +module_exit(nfnotif_tg_exit);
> +
> +MODULE_AUTHOR("Samuel Ortiz <samuel.ortiz@intel.com>");
> +MODULE_DESCRIPTION("Xtables: userspace notification");
> +MODULE_LICENSE("GPL v2");
> --
> 1.7.1
>
> --
> Intel Open Source Technology Centre
> http://oss.intel.com/
> --
> To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



-- 
Regards,
Changli Gao(xiaosuo@gmail.com)
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" 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 repost] sched: export sched_set/getaffinity to modules
From: Sridhar Samudrala @ 2010-07-13  6:59 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Oleg Nesterov, Peter Zijlstra, Tejun Heo, Ingo Molnar, netdev,
	lkml, kvm@vger.kernel.org, Andrew Morton, Dmitri Vorobiev,
	Jiri Kosina, Thomas Gleixner, Andi Kleen
In-Reply-To: <20100704090005.GA8078@redhat.com>

On 7/4/2010 2:00 AM, Michael S. Tsirkin wrote:
> On Fri, Jul 02, 2010 at 11:06:37PM +0200, Oleg Nesterov wrote:
>    
>> On 07/02, Peter Zijlstra wrote:
>>      
>>> On Fri, 2010-07-02 at 11:01 -0700, Sridhar Samudrala wrote:
>>>        
>>>>   Does  it (Tejun's kthread_clone() patch) also  inherit the
>>>> cgroup of the caller?
>>>>          
>>> Of course, its a simple do_fork() which inherits everything just as you
>>> would expect from a similar sys_clone()/sys_fork() call.
>>>        
>> Yes. And I'm afraid it can inherit more than we want. IIUC, this is called
>> from ioctl(), right?
>>
>> Then the new thread becomes the natural child of the caller, and it shares
>> ->mm with the parent. And files, dup_fd() without CLONE_FS.
>>
>> Signals. Say, if you send SIGKILL to this new thread, it can't sleep in
>> TASK_INTERRUPTIBLE or KILLABLE after that. And this SIGKILL can be sent
>> just because the parent gets SIGQUIT or abother coredumpable signal.
>> Or the new thread can recieve SIGSTOP via ^Z.
>>
>> Perhaps this is OK, I do not know. Just to remind that kernel_thread()
>> is merely clone(CLONE_VM).
>>
>> Oleg.
>>      
>
> Right. Doing this might break things like flush.  The signal and exit
> behaviour needs to be examined carefully. I am also unsure whether
> using such threads might be more expensive than inheriting kthreadd.
>
>    
Should we just leave it to the userspace to set the cgroup/cpumask after 
qemu starts the guest and
the vhost threads?

Thanks
Sridhar

^ permalink raw reply

* [PATCH] rfs: call sock_rps_record_flow() in tcp_splice_read()
From: Changli Gao @ 2010-07-13  7:00 UTC (permalink / raw)
  To: David S. Miller
  Cc: David S. Miller, Alexey Kuznetsov, Pekka Savola (ipv6),
	James Morris, Hideaki YOSHIFUJI, Patrick McHardy, Tom Herbert,
	netdev, Changli Gao

rfs: call sock_rps_record_flow() in tcp_splice_read()

call sock_rps_record_flow() in tcp_splice_read(), so the applications using
splice(2) or sendfile(2) can utilize RFS.

Signed-off-by: Changli Gao <xiaosuo@gmail.com>
----
 net/ipv4/tcp.c |    1 +
 1 file changed, 1 insertion(+)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 9fce8a8..86b9f67 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -608,6 +608,7 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos,
 	ssize_t spliced;
 	int ret;
 
+	sock_rps_record_flow(sk);
 	/*
 	 * We can't seek on a socket input
 	 */

^ permalink raw reply related

* [PATCH] xfrm: do not assume that template resolving always returns xfrms
From: Timo Teräs @ 2010-07-13  7:29 UTC (permalink / raw)
  To: netdev, David Miller, linux; +Cc: Timo Teräs
In-Reply-To: <20100712.212041.236240543.davem@davemloft.net>

xfrm_resolve_and_create_bundle() assumed that, if policies indicated
presence of xfrms, bundle template resolution would always return
some xfrms. This is not true for 'use' level policies which can
result in no xfrm's being applied if there is no suitable xfrm states.
This fixes a crash by this incorrect assumption.

Reported-by: George Spelvin <linux@horizon.com>
Bisected-by: George Spelvin <linux@horizon.com>
Tested-by: George Spelvin <linux@horizon.com>
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
---
 net/xfrm/xfrm_policy.c |   15 +++++++++++++--
 1 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index af1c173..a7ec5a8 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1594,8 +1594,8 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
 
 	/* Try to instantiate a bundle */
 	err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family);
-	if (err < 0) {
-		if (err != -EAGAIN)
+	if (err <= 0) {
+		if (err != 0 && err != -EAGAIN)
 			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
 		return ERR_PTR(err);
 	}
@@ -1678,6 +1678,13 @@ xfrm_bundle_lookup(struct net *net, struct flowi *fl, u16 family, u8 dir,
 			goto make_dummy_bundle;
 		dst_hold(&xdst->u.dst);
 		return oldflo;
+	} else if (new_xdst == NULL) {
+		num_xfrms = 0;
+		if (oldflo == NULL)
+			goto make_dummy_bundle;
+		xdst->num_xfrms = 0;
+		dst_hold(&xdst->u.dst);
+		return oldflo;
 	}
 
 	/* Kill the previous bundle */
@@ -1760,6 +1767,10 @@ restart:
 				xfrm_pols_put(pols, num_pols);
 				err = PTR_ERR(xdst);
 				goto dropdst;
+			} else if (xdst == NULL) {
+				num_xfrms = 0;
+				drop_pols = num_pols;
+				goto no_transform;
 			}
 
 			spin_lock_bh(&xfrm_policy_sk_bundle_lock);
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH] netfilter: xtables: userspace notification target
From: Pablo Neira Ayuso @ 2010-07-13  8:50 UTC (permalink / raw)
  To: Changli Gao
  Cc: Samuel Ortiz, Patrick McHardy, David S. Miller, netdev,
	netfilter-devel, Luciano Coelho
In-Reply-To: <AANLkTil2EgQbzUqYNHAYpIWJvyyE6AWq1TpvxrqVsD7k@mail.gmail.com>

On 13/07/10 08:18, Changli Gao wrote:
> On Tue, Jul 13, 2010 at 8:11 AM, Samuel Ortiz <sameo@linux.intel.com> wrote:
>>
>> The userspace notification Xtables target sends a netlink notification
>> whenever a packet hits the target. Notifications have a label attribute
>> for userspace to match it against a previously set rule. The rules also
>> take a --all option to switch between sending a notification for all
>> packets or for the first one only.
>> Userspace can also send a netlink message to toggle this switch while the
>> target is in place. This target uses the nefilter netlink framework.
>>
>> This target combined with various matches (quota, rateest, etc..) allows
>> userspace to make decisions on interfaces handling. One could for example
>> decide to switch between power saving modes depending on estimated rate
>> thresholds.
>>
> 
> It much like the following iptables rules.
> 
> iptables -N log_and_drop
> iptables -A log_and_drop -j NFLOG --nflog-group 1 --nflog-prefix "log_and_drop"
> iptables -A log_and_drop -j DROP
> 
> ...
> iptables ... -m quota --quota-bytes 20000 -j log_and_drop
> ...

Indeed, this looks to me like something that you can do with NFLOG and
some combination of matches.

^ permalink raw reply

* [PATCH NEXT 2/5] qlcnic: disable tx timeout recovery
From: amit.salecha @ 2010-07-13  9:46 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman, Amit Kumar Salecha
In-Reply-To: <1279014420-8829-1-git-send-email-amit.salecha@qlogic.com>

From: Amit Kumar Salecha <amit.salecha@qlogic.com>

Disable tx timeout recovery, if auto_fw_reset is disable

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_main.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 4d18313..d511fd1 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -2581,7 +2581,8 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
 		if (adapter->need_fw_reset)
 			goto detach;
 
-		if (adapter->reset_context) {
+		if (adapter->reset_context &&
+				auto_fw_reset == AUTO_FW_RESET_ENABLED) {
 			qlcnic_reset_hw_context(adapter);
 			adapter->netdev->trans_start = jiffies;
 		}
@@ -2594,7 +2595,8 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
 
 	qlcnic_dev_request_reset(adapter);
 
-	clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state);
+	if ((auto_fw_reset == AUTO_FW_RESET_ENABLED))
+		clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state);
 
 	dev_info(&netdev->dev, "firmware hang detected\n");
 
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT 3/5] qlcnic: fix netdev notifier in error path
From: amit.salecha @ 2010-07-13  9:46 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman, Amit Kumar Salecha
In-Reply-To: <1279014420-8829-1-git-send-email-amit.salecha@qlogic.com>

From: Amit Kumar Salecha <amit.salecha@qlogic.com>

netdev notifier are not unregistered if pci_register_driver fails.

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_main.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index d511fd1..c8275f0 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -3451,6 +3451,7 @@ static struct pci_driver qlcnic_driver = {
 
 static int __init qlcnic_init_module(void)
 {
+	int ret;
 
 	printk(KERN_INFO "%s\n", qlcnic_driver_string);
 
@@ -3459,8 +3460,15 @@ static int __init qlcnic_init_module(void)
 	register_inetaddr_notifier(&qlcnic_inetaddr_cb);
 #endif
 
+	ret = pci_register_driver(&qlcnic_driver);
+	if (ret) {
+#ifdef CONFIG_INET
+		unregister_inetaddr_notifier(&qlcnic_inetaddr_cb);
+		unregister_netdevice_notifier(&qlcnic_netdev_cb);
+#endif
+	}
 
-	return pci_register_driver(&qlcnic_driver);
+	return ret;
 }
 
 module_init(qlcnic_init_module);
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT 0/5]qlcnic: aer support
From: amit.salecha @ 2010-07-13  9:46 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman


Hi
   Series of 5 to support aer and minor fixes.
   Please apply them on net-next.
-Amit

^ permalink raw reply

* [PATCH NEXT 5/5] qlcnic: restore NPAR config data after recovery
From: amit.salecha @ 2010-07-13  9:47 UTC (permalink / raw)
  To: davem
  Cc: netdev, ameen.rahman, Anirban Chakraborty, Rajesh Borundia,
	Amit Kumar Salecha
In-Reply-To: <1279014420-8829-1-git-send-email-amit.salecha@qlogic.com>

From: Anirban Chakraborty <anirban.chakraborty@qlogic.com>

NPAR configuration which is programmed in fw, need to
restore after fw recovery.

Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic.h      |    3 +-
 drivers/net/qlcnic/qlcnic_ctx.c  |    2 +
 drivers/net/qlcnic/qlcnic_main.c |   80 ++++++++++++++++++++++++++++++--------
 3 files changed, 67 insertions(+), 18 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 0644642..9f96298 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -949,7 +949,6 @@ struct qlcnic_adapter {
 	u8 has_link_events;
 	u8 fw_type;
 	u16 tx_context_id;
-	u16 mtu;
 	u16 is_up;
 
 	u16 link_speed;
@@ -1044,6 +1043,8 @@ struct qlcnic_pci_info {
 
 struct qlcnic_npar_info {
 	u16	vlan_id;
+	u16	min_bw;
+	u16	max_bw;
 	u8	phy_port;
 	u8	type;
 	u8	active;
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index cdd44b4..cc5d861 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -636,6 +636,8 @@ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter,
 			QLCNIC_CDRP_CMD_GET_NIC_INFO);
 
 	if (err == QLCNIC_RCODE_SUCCESS) {
+		npar_info->pci_func = le16_to_cpu(nic_info->pci_func);
+		npar_info->op_mode = le16_to_cpu(nic_info->op_mode);
 		npar_info->phys_port = le16_to_cpu(nic_info->phys_port);
 		npar_info->switch_mode = le16_to_cpu(nic_info->switch_mode);
 		npar_info->max_tx_ques = le16_to_cpu(nic_info->max_tx_ques);
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 462cb6b..38c8d9c 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -507,6 +507,8 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
 			adapter->npars[pfn].type = pci_info[i].type;
 			adapter->npars[pfn].phy_port = pci_info[i].default_port;
 			adapter->npars[pfn].mac_learning = DEFAULT_MAC_LEARN;
+			adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw;
+			adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw;
 		}
 
 		for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++)
@@ -771,6 +773,50 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
 }
 
 static int
+qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
+{
+	int i, err = 0;
+	struct qlcnic_npar_info *npar;
+	struct qlcnic_info nic_info;
+
+	if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)
+				|| !adapter->need_fw_reset)
+		return 0;
+
+	if (adapter->op_mode == QLCNIC_MGMT_FUNC) {
+		/* Set the NPAR config data after FW reset */
+		for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
+			npar = &adapter->npars[i];
+			if (npar->type != QLCNIC_TYPE_NIC)
+				continue;
+			err = qlcnic_get_nic_info(adapter, &nic_info, i);
+			if (err)
+				goto err_out;
+			nic_info.min_tx_bw = npar->min_bw;
+			nic_info.max_tx_bw = npar->max_bw;
+			err = qlcnic_set_nic_info(adapter, &nic_info);
+			if (err)
+				goto err_out;
+
+			if (npar->enable_pm) {
+				err = qlcnic_config_port_mirroring(adapter,
+						npar->dest_npar, 1, i);
+				if (err)
+					goto err_out;
+
+			}
+			npar->mac_learning = DEFAULT_MAC_LEARN;
+			npar->host_vlan_tag = 0;
+			npar->promisc_mode = 0;
+			npar->discard_tagged = 0;
+			npar->vlan_id = 0;
+		}
+	}
+err_out:
+	return err;
+}
+
+static int
 qlcnic_start_firmware(struct qlcnic_adapter *adapter)
 {
 	int val, err, first_boot;
@@ -834,10 +880,9 @@ wait_init:
 	qlcnic_idc_debug_info(adapter, 1);
 
 	qlcnic_check_options(adapter);
-
-	if (adapter->flags & QLCNIC_ESWITCH_ENABLED &&
-		adapter->op_mode != QLCNIC_NON_PRIV_FUNC)
-		qlcnic_dev_set_npar_ready(adapter);
+	if (qlcnic_reset_npar_config(adapter))
+		goto err_out;
+	qlcnic_dev_set_npar_ready(adapter);
 
 	adapter->need_fw_reset = 0;
 
@@ -2486,6 +2531,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
 {
 	u32 state;
 
+	adapter->need_fw_reset = 1;
 	if (qlcnic_api_lock(adapter))
 		return;
 
@@ -2506,6 +2552,9 @@ qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter)
 {
 	u32 state;
 
+	if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
+		adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
+		return;
 	if (qlcnic_api_lock(adapter))
 		return;
 
@@ -3154,9 +3203,8 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
 	struct device *dev = container_of(kobj, struct device, kobj);
 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
 	struct qlcnic_esw_func_cfg *esw_cfg;
-	u8 id, discard_tagged, promsc_mode, mac_learn;
-	u8 vlan_tagging, pci_func, vlan_id;
 	int count, rem, i, ret;
+	u8 id, pci_func;
 
 	count	= size / sizeof(struct qlcnic_esw_func_cfg);
 	rem	= size % sizeof(struct qlcnic_esw_func_cfg);
@@ -3171,17 +3219,13 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
 	for (i = 0; i < count; i++) {
 		pci_func = esw_cfg[i].pci_func;
 		id = adapter->npars[pci_func].phy_port;
-		vlan_tagging = esw_cfg[i].host_vlan_tag;
-		promsc_mode = esw_cfg[i].promisc_mode;
-		mac_learn = esw_cfg[i].mac_learning;
-		vlan_id	= esw_cfg[i].vlan_id;
-		discard_tagged = esw_cfg[i].discard_tagged;
-		ret = qlcnic_config_switch_port(adapter, id, vlan_tagging,
-						discard_tagged,
-						promsc_mode,
-						mac_learn,
-						pci_func,
-						vlan_id);
+		ret = qlcnic_config_switch_port(adapter, id,
+						esw_cfg[i].host_vlan_tag,
+						esw_cfg[i].discard_tagged,
+						esw_cfg[i].promisc_mode,
+						esw_cfg[i].mac_learning,
+						esw_cfg[i].pci_func,
+						esw_cfg[i].vlan_id);
 		if (ret)
 			return ret;
 	}
@@ -3282,6 +3326,8 @@ qlcnic_sysfs_write_npar_config(struct file *file, struct kobject *kobj,
 		ret = qlcnic_set_nic_info(adapter, &nic_info);
 		if (ret)
 			return ret;
+		adapter->npars[i].min_bw = nic_info.min_tx_bw;
+		adapter->npars[i].max_bw = nic_info.max_tx_bw;
 	}
 
 	return size;
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT 1/5] qlcnic: fix pause params setting
From: amit.salecha @ 2010-07-13  9:46 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman, Rajesh Borundia, Amit Kumar Salecha
In-Reply-To: <1279014420-8829-1-git-send-email-amit.salecha@qlogic.com>

From: Rajesh Borundia <rajesh.borundia@qlogic.com>

Turning off rx pause param and autoneg param is not supported so
return error in that case.

Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_ethtool.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index baf5a52..8599993 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -578,8 +578,13 @@ qlcnic_set_pauseparam(struct net_device *netdev,
 		}
 		QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
 	} else if (adapter->ahw.port_type == QLCNIC_XGBE) {
+
+		if (!pause->rx_pause || pause->autoneg)
+			return -EOPNOTSUPP;
+
 		if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
 			return -EIO;
+
 		val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
 		if (port == 0) {
 			if (pause->tx_pause)
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT 4/5] qlcnic: aer support
From: amit.salecha @ 2010-07-13  9:46 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman, Sucheta Chakraborty, Amit Kumar Salecha
In-Reply-To: <1279014420-8829-1-git-send-email-amit.salecha@qlogic.com>

From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>

Pci error recovery support added.

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic.h      |    1 +
 drivers/net/qlcnic/qlcnic_main.c |  137 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 137 insertions(+), 1 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 02a50e6..0644642 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -911,6 +911,7 @@ struct qlcnic_mac_req {
 #define __QLCNIC_DEV_UP 		1
 #define __QLCNIC_RESETTING		2
 #define __QLCNIC_START_FW 		4
+#define __QLCNIC_AER			5
 
 #define QLCNIC_INTERRUPT_TEST		1
 #define QLCNIC_LOOPBACK_TEST		2
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index c8275f0..462cb6b 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -34,6 +34,7 @@
 #include <linux/ipv6.h>
 #include <linux/inetdevice.h>
 #include <linux/sysfs.h>
+#include <linux/aer.h>
 
 MODULE_DESCRIPTION("QLogic 1/10 GbE Converged/Intelligent Ethernet Driver");
 MODULE_LICENSE("GPL");
@@ -1306,6 +1307,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_out_disable_pdev;
 
 	pci_set_master(pdev);
+	pci_enable_pcie_error_reporting(pdev);
 
 	netdev = alloc_etherdev(sizeof(struct qlcnic_adapter));
 	if (!netdev) {
@@ -1437,6 +1439,7 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev)
 
 	qlcnic_release_firmware(adapter);
 
+	pci_disable_pcie_error_reporting(pdev);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
@@ -2521,6 +2524,9 @@ static void
 qlcnic_schedule_work(struct qlcnic_adapter *adapter,
 		work_func_t func, int delay)
 {
+	if (test_bit(__QLCNIC_AER, &adapter->state))
+		return;
+
 	INIT_DELAYED_WORK(&adapter->fw_work, func);
 	schedule_delayed_work(&adapter->fw_work, round_jiffies_relative(delay));
 }
@@ -2631,6 +2637,128 @@ reschedule:
 	qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY);
 }
 
+static int qlcnic_is_first_func(struct pci_dev *pdev)
+{
+	struct pci_dev *oth_pdev;
+	int val = pdev->devfn;
+
+	while (val-- > 0) {
+		oth_pdev = pci_get_domain_bus_and_slot(pci_domain_nr
+			(pdev->bus), pdev->bus->number,
+			PCI_DEVFN(PCI_SLOT(pdev->devfn), val));
+
+		if (oth_pdev && (oth_pdev->current_state != PCI_D3cold))
+			return 0;
+	}
+	return 1;
+}
+
+static int qlcnic_attach_func(struct pci_dev *pdev)
+{
+	int err, first_func;
+	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
+	struct net_device *netdev = adapter->netdev;
+
+	pdev->error_state = pci_channel_io_normal;
+
+	err = pci_enable_device(pdev);
+	if (err)
+		return err;
+
+	pci_set_power_state(pdev, PCI_D0);
+	pci_set_master(pdev);
+	pci_restore_state(pdev);
+
+	first_func = qlcnic_is_first_func(pdev);
+
+	if (qlcnic_api_lock(adapter))
+		return -EINVAL;
+
+	if (first_func) {
+		adapter->need_fw_reset = 1;
+		set_bit(__QLCNIC_START_FW, &adapter->state);
+		QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITIALIZING);
+		QLCDB(adapter, DRV, "Restarting fw\n");
+	}
+	qlcnic_api_unlock(adapter);
+
+	err = adapter->nic_ops->start_firmware(adapter);
+	if (err)
+		return err;
+
+	qlcnic_clr_drv_state(adapter);
+	qlcnic_setup_intr(adapter);
+
+	if (netif_running(netdev)) {
+		err = qlcnic_attach(adapter);
+		if (err) {
+			qlcnic_clr_all_drv_state(adapter);
+			clear_bit(__QLCNIC_AER, &adapter->state);
+			netif_device_attach(netdev);
+			return err;
+		}
+
+		err = qlcnic_up(adapter, netdev);
+		if (err)
+			goto done;
+
+		qlcnic_config_indev_addr(netdev, NETDEV_UP);
+	}
+ done:
+	netif_device_attach(netdev);
+	return err;
+}
+
+static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev,
+						pci_channel_state_t state)
+{
+	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
+	struct net_device *netdev = adapter->netdev;
+
+	if (state == pci_channel_io_perm_failure)
+		return PCI_ERS_RESULT_DISCONNECT;
+
+	if (state == pci_channel_io_normal)
+		return PCI_ERS_RESULT_RECOVERED;
+
+	set_bit(__QLCNIC_AER, &adapter->state);
+	netif_device_detach(netdev);
+
+	cancel_delayed_work_sync(&adapter->fw_work);
+
+	if (netif_running(netdev))
+		qlcnic_down(adapter, netdev);
+
+	qlcnic_detach(adapter);
+	qlcnic_teardown_intr(adapter);
+
+	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
+
+	return PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t qlcnic_io_slot_reset(struct pci_dev *pdev)
+{
+	return qlcnic_attach_func(pdev) ? PCI_ERS_RESULT_DISCONNECT :
+				PCI_ERS_RESULT_RECOVERED;
+}
+
+static void qlcnic_io_resume(struct pci_dev *pdev)
+{
+	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
+
+	pci_cleanup_aer_uncorrect_error_status(pdev);
+
+	if ((QLCRD32(adapter, QLCNIC_CRB_DEV_STATE) == QLCNIC_DEV_READY) &&
+			   (test_and_clear_bit(__QLCNIC_AER, &adapter->state)))
+		qlcnic_schedule_work(adapter, qlcnic_fw_poll_work,
+						FW_POLL_DELAY);
+}
+
+
 static int
 qlcnicvf_start_firmware(struct qlcnic_adapter *adapter)
 {
@@ -3436,6 +3564,11 @@ static void
 qlcnic_config_indev_addr(struct net_device *dev, unsigned long event)
 { }
 #endif
+static struct pci_error_handlers qlcnic_err_handler = {
+	.error_detected = qlcnic_io_error_detected,
+	.slot_reset = qlcnic_io_slot_reset,
+	.resume = qlcnic_io_resume,
+};
 
 static struct pci_driver qlcnic_driver = {
 	.name = qlcnic_driver_name,
@@ -3446,7 +3579,9 @@ static struct pci_driver qlcnic_driver = {
 	.suspend = qlcnic_suspend,
 	.resume = qlcnic_resume,
 #endif
-	.shutdown = qlcnic_shutdown
+	.shutdown = qlcnic_shutdown,
+	.err_handler = &qlcnic_err_handler
+
 };
 
 static int __init qlcnic_init_module(void)
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH -mmotm 00/30] [RFC] swap over nfs -v21
From: Xiaotian Feng @ 2010-07-13 10:16 UTC (permalink / raw)
  To: linux-mm, linux-nfs, netdev
  Cc: riel, cl, a.p.zijlstra, Xiaotian Feng, linux-kernel, lwang,
	penberg, akpm, davem

Hi,

Here's the latest version of swap over NFS series since -v20 last October. We decide to push
this feature as it is useful for NAS or virt environment.

The patches are against the mmotm-2010-07-01. We can split the patchset into following parts:

Patch 1 - 12: provides a generic reserve framework. This framework
could also be used to get rid of some of the __GFP_NOFAIL users.

Patch 13 - 15: Provide some generic network infrastructure needed later on.

Patch 16 - 21: reserve a little pool to act as a receive buffer, this allows us to
inspect packets before tossing them.

Patch 22 - 23: Generic vm infrastructure to handle swapping to a filesystem instead of a block
device.

Patch 24 - 27: convert NFS to make use of the new network and vm infrastructure to
provide swap over NFS.

Patch 28 - 30: minor bug fixing with latest -mmotm.

[some history]
v19: http://lwn.net/Articles/301915/
v20: http://lwn.net/Articles/355350/

Changes since v20:
	- rebased to mmotm-2010-07-01
	- dropped the null pointer deref patch for the root cause is wrong SWP_FILE enum
	- some minor build fixes
	- fix a null pointer deref with mmotm-2010-07-01
	- fix a bug when swap with multi files on the same nfs server

Regards
Xiaotian

--
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

* [PATCH -mmotm 01/30] mm: serialize access to min_free_kbytes
From: Xiaotian Feng @ 2010-07-13 10:17 UTC (permalink / raw)
  To: linux-mm, linux-nfs, netdev
  Cc: riel, cl, a.p.zijlstra, Xiaotian Feng, linux-kernel, lwang,
	penberg, akpm, davem
In-Reply-To: <20100713101650.2835.15245.sendpatchset@danny.redhat>

>From bc55bacd6bcc0f8a69c0d7e0d554c78237233e07 Mon Sep 17 00:00:00 2001
From: Xiaotian Feng <dfeng@redhat.com>
Date: Mon, 12 Jul 2010 17:58:34 +0800
Subject: [PATCH 01/30] mm: serialize access to min_free_kbytes

There is a small race between the procfs caller and the memory hotplug caller
of setup_per_zone_wmarks(). Not a big deal, but the next patch will add yet
another caller. Time to close the gap.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
Signed-off-by: Xiaotian Feng <dfeng@redhat.com>
---
 mm/page_alloc.c |   16 +++++++++++++---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 50a6d10..ebf0af7 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -165,6 +165,7 @@ static char * const zone_names[MAX_NR_ZONES] = {
 	 "Movable",
 };
 
+static DEFINE_SPINLOCK(min_free_lock);
 int min_free_kbytes = 1024;
 
 static unsigned long __meminitdata nr_kernel_pages;
@@ -4839,13 +4840,13 @@ static void setup_per_zone_lowmem_reserve(void)
 }
 
 /**
- * setup_per_zone_wmarks - called when min_free_kbytes changes
+ * __setup_per_zone_wmarks - called when min_free_kbytes changes
  * or when memory is hot-{added|removed}
  *
  * Ensures that the watermark[min,low,high] values for each zone are set
  * correctly with respect to min_free_kbytes.
  */
-void setup_per_zone_wmarks(void)
+static void __setup_per_zone_wmarks(void)
 {
 	unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10);
 	unsigned long lowmem_pages = 0;
@@ -4943,6 +4944,15 @@ static void __init setup_per_zone_inactive_ratio(void)
 		calculate_zone_inactive_ratio(zone);
 }
 
+void setup_per_zone_wmarks(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&min_free_lock, flags);
+	__setup_per_zone_wmarks();
+	spin_unlock_irqrestore(&min_free_lock, flags);
+}
+
 /*
  * Initialise min_free_kbytes.
  *
@@ -4978,7 +4988,7 @@ static int __init init_per_zone_wmark_min(void)
 		min_free_kbytes = 128;
 	if (min_free_kbytes > 65536)
 		min_free_kbytes = 65536;
-	setup_per_zone_wmarks();
+	__setup_per_zone_wmarks();
 	setup_per_zone_lowmem_reserve();
 	setup_per_zone_inactive_ratio();
 	return 0;
-- 
1.7.1.1

--
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

* [PATCH -mmotm 02/30] Swap over network documentation
From: Xiaotian Feng @ 2010-07-13 10:17 UTC (permalink / raw)
  To: linux-mm, linux-nfs, netdev
  Cc: riel, cl, a.p.zijlstra, Xiaotian Feng, linux-kernel, lwang,
	penberg, akpm, davem
In-Reply-To: <20100713101650.2835.15245.sendpatchset@danny.redhat>

>From 8c68e4dc644be32cd82ba9711ba3ef89cb687cdf Mon Sep 17 00:00:00 2001
From: Xiaotian Feng <dfeng@redhat.com>
Date: Mon, 12 Jul 2010 17:59:16 +0800
Subject: [PATCH 02/30] Swap over network documentation

Document describing the problem and proposed solution

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
Signed-off-by: Xiaotian Feng <dfeng@redhat.com>
---
 Documentation/network-swap.txt |  268 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 268 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/network-swap.txt

diff --git a/Documentation/network-swap.txt b/Documentation/network-swap.txt
new file mode 100644
index 0000000..760af2e
--- /dev/null
+++ b/Documentation/network-swap.txt
@@ -0,0 +1,268 @@
+
+Problem:
+   When Linux needs to allocate memory it may find that there is
+   insufficient free memory so it needs to reclaim space that is in
+   use but not needed at the moment.  There are several options:
+
+   1/ Shrink a kernel cache such as the inode or dentry cache.  This
+      is fairly easy but provides limited returns.
+   2/ Discard 'clean' pages from the page cache.  This is easy, and
+      works well as long as there are clean pages in the page cache.
+      Similarly clean 'anonymous' pages can be discarded - if there
+      are any.
+   3/ Write out some dirty page-cache pages so that they become clean.
+      The VM limits the number of dirty page-cache pages to e.g. 40%
+      of available memory so that (among other reasons) a "sync" will
+      not take excessively long.  So there should never be excessive
+      amounts of dirty pagecache.
+      Writing out dirty page-cache pages involves work by the
+      filesystem which may need to allocate memory itself.  To avoid
+      deadlock, filesystems use GFP_NOFS when allocating memory on the
+      write-out path.  When this is used, cleaning dirty page-cache
+      pages is not an option so if the filesystem finds that  memory
+      is tight, another option must be found.
+   4/ Write out dirty anonymous pages to the "Swap" partition/file.
+      This is the most interesting for a couple of reasons.
+      a/ Unlike dirty page-cache pages, there is no need to write anon
+         pages out unless we are actually short of memory.  Thus they
+         tend to be left to last.
+      b/ Anon pages tend to be updated randomly and unpredictably, and
+         flushing them out of memory can have a very significant
+         performance impact on the process using them.  This contrasts
+         with page-cache pages which are often written sequentially
+         and often treated as "write-once, read-many".
+      So anon pages tend to be left until last to be cleaned, and may
+      be the only cleanable pages while there are still some dirty
+      page-cache pages (which are waiting on a GFP_NOFS allocation).
+
+[I don't find the above wholly satisfying.  There seems to be too much
+ hand-waving.  If someone can provide better text explaining why
+ swapout is a special case, that would be great.]
+
+So we need to be able to write to the swap file/partition without
+needing to allocate any memory ... or only a small well controlled
+amount.
+
+The VM reserves a small amount of memory that can only be allocated
+for use as part of the swap-out procedure.  It is only available to
+processes with the PF_MEMALLOC flag set, which is typically just the
+memory cleaner.
+
+Traditionally swap-out is performed directly to block devices (swap
+files on block-device filesystems are supported by examining the
+mapping from file offset to device offset in advance, and then using
+the device offsets to write directly to the device).  Block devices
+are (required to be) written to pre-allocate any memory that might be
+needed during write-out, and to block when the pre-allocated memory is
+exhausted and no other memory is available.  They can be sure not to
+block forever as the pre-allocated memory will be returned as soon as
+the data it is being used for has been written out.  The primary
+mechanism for pre-allocating memory is called "mempools".
+
+This approach does not work for writing anonymous pages
+(i.e. swapping) over a network, using e.g NFS or NBD or iSCSI.
+
+
+The main reason that it does not work is that when data from an anon
+page is written to the network, we must wait for a reply to confirm
+the data is safe.  Receiving that reply will consume memory and,
+significantly, we need to allocate memory to an incoming packet before
+we can tell if it is the reply we are waiting for or not.
+
+The secondary reason is that the network code is not written to use
+mempools and in most cases does not need to use them.  Changing all
+allocations in the networking layer to use mempools would be quite
+intrusive, and would waste memory, and probably cause a slow-down in
+the common case of not swapping over the network.
+
+These problems are addressed by enhancing the system of memory
+reserves used by PF_MEMALLOC and requiring any in-kernel networking
+client that is used for swap-out to indicate which sockets are used
+for swapout so they can be handled specially in low memory situations.
+
+There are several major parts to this enhancement:
+
+1/ page->reserve, GFP_MEMALLOC
+
+  To handle low memory conditions we need to know when those
+  conditions exist.  Having a global "low on memory" flag seems easy,
+  but its implementation is problematic.  Instead we make it possible
+  to tell if a recent memory allocation required use of the emergency
+  memory pool.
+  For pages returned by alloc_page, the new page->reserve flag
+  can be tested.  If this is set, then a low memory condition was
+  current when the page was allocated, so the memory should be used
+  carefully. (Because low memory conditions are transient, this
+  state is kept in an overloaded member instead of in page flags, which
+  would suggest a more permanent state.)
+
+  For memory allocated using slab/slub: If a page that is added to a
+  kmem_cache is found to have page->reserve set, then a  s->reserve
+  flag is set for the whole kmem_cache.  Further allocations will only
+  be returned from that page (or any other page in the cache) if they
+  are emergency allocation (i.e. PF_MEMALLOC or GFP_MEMALLOC is set).
+  Non-emergency allocations will block in alloc_page until a
+  non-reserve page is available.  Once a non-reserve page has been
+  added to the cache, the s->reserve flag on the cache is removed.
+
+  Because slab objects have no individual state its hard to pass
+  reserve state along, the current code relies on a regular alloc
+  failing. There are various allocation wrappers help here.
+
+  This allows us to
+   a/ request use of the emergency pool when allocating memory
+     (GFP_MEMALLOC), and
+   b/ to find out if the emergency pool was used.
+
+2/ SK_MEMALLOC, sk_buff->emergency.
+
+  When memory from the reserve is used to store incoming network
+  packets, the memory must be freed (and the packet dropped) as soon
+  as we find out that the packet is not for a socket that is used for
+  swap-out.
+  To achieve this we have an ->emergency flag for skbs, and an
+  SK_MEMALLOC flag for sockets.
+  When memory is allocated for an skb, it is allocated with
+  GFP_MEMALLOC (if we are currently swapping over the network at
+  all).  If a subsequent test shows that the emergency pool was used,
+  ->emergency is set.
+  When the skb is finally attached to its destination socket, the
+  SK_MEMALLOC flag on the socket is tested.  If the skb has
+  ->emergency set, but the socket does not have SK_MEMALLOC set, then
+  the skb is immediately freed and the packet is dropped.
+  This ensures that reserve memory is never queued on a socket that is
+  not used for swapout.
+
+  Similarly, if an skb is ever queued for delivery to user-space for
+  example by netfilter, the ->emergency flag is tested and the skb is
+  released if ->emergency is set. (so obviously the storage route may
+  not pass through a userspace helper, otherwise the packets will never
+  arrive and we'll deadlock)
+
+  This ensures that memory from the emergency reserve can be used to
+  allow swapout to proceed, but will not get caught up in any other
+  network queue.
+
+
+3/ pages_emergency
+
+  The above would be sufficient if the total memory below the lowest
+  memory watermark (i.e the size of the emergency reserve) were known
+  to be enough to hold all transient allocations needed for writeout.
+  I'm a little blurry on how big the current emergency pool is, but it
+  isn't big and certainly hasn't been sized to allow network traffic
+  to consume any.
+
+  We could simply make the size of the reserve bigger. However in the
+  common case that we are not swapping over the network, that would be
+  a waste of memory.
+
+  So a new "watermark" is defined: pages_emergency.  This is
+  effectively added to the current low water marks, so that pages from
+  this emergency pool can only be allocated if one of PF_MEMALLOC or
+  GFP_MEMALLOC are set.
+
+  pages_emergency can be changed dynamically based on need.  When
+  swapout over the network is required, pages_emergency is increased
+  to cover the maximum expected load.  When network swapout is
+  disabled, pages_emergency is decreased.
+
+  To determine how much to increase it by, we introduce reservation
+  groups....
+
+3a/ reservation groups
+
+  The memory used transiently for swapout can be in a number of
+  different places.  e.g. the network route cache, the network
+  fragment cache, in transit between network card and socket, or (in
+  the case of NFS) in sunrpc data structures awaiting a reply.
+  We need to ensure each of these is limited in the amount of memory
+  they use, and that the maximum is included in the reserve.
+
+  The memory required by the network layer only needs to be reserved
+  once, even if there are multiple swapout paths using the network
+  (e.g. NFS and NDB and iSCSI, though using all three for swapout at
+  the same time would be unusual).
+
+  So we create a tree of reservation groups.  The network might
+  register a collection of reservations, but not mark them as being in
+  use.  NFS and sunrpc might similarly register a collection of
+  reservations, and attach it to the network reservations as it
+  depends on them.
+  When swapout over NFS is requested, the NFS/sunrpc reservations are
+  activated which implicitly activates the network reservations.
+
+  The total new reservation is added to pages_emergency.
+
+  Provided each memory usage stays beneath the registered limit (at
+  least when allocating memory from reserves), the system will never
+  run out of emergency memory, and swapout will not deadlock.
+
+  It is worth noting here that it is not critical that each usage
+  stays beneath the limit 100% of the time.  Occasional excess is
+  acceptable provided that the memory will be freed  again within a
+  short amount of time that does *not* require waiting for any event
+  that itself might require memory.
+  This is because, at all stages of transmit and receive, it is
+  acceptable to discard all transient memory associated with a
+  particular writeout and try again later.  On transmit, the page can
+  be re-queued for later transmission.  On receive, the packet can be
+  dropped assuming that the peer will resend after a timeout.
+
+  Thus allocations that are truly transient and will be freed without
+  blocking do not strictly need to be reserved for.  Doing so might
+  still be a good idea to ensure forward progress doesn't take too
+  long.
+
+4/ low-mem accounting
+
+  Most places that might hold on to emergency memory (e.g. route
+  cache, fragment cache etc) already place a limit on the amount of
+  memory that they can use.  This limit can simply be reserved using
+  the above mechanism and no more needs to be done.
+
+  However some memory usage might not be accounted with sufficient
+  firmness to allow an appropriate emergency reservation.  The
+  in-flight skbs for incoming packets is one such example.
+
+  To support this, a low-overhead mechanism for accounting memory
+  usage against the reserves is provided.  This mechanism uses the
+  same data structure that is used to store the emergency memory
+  reservations through the addition of a 'usage' field.
+
+  Before we attempt allocation from the memory reserves, we much check
+  if the resulting 'usage' is below the reservation. If so, we increase
+  the usage and attempt the allocation (which should succeed). If
+  the projected 'usage' exceeds the reservation we'll either fail the
+  allocation, or wait for 'usage' to decrease enough so that it would
+  succeed, depending on __GFP_WAIT.
+
+  When memory that was allocated for that purpose is freed, the
+  'usage' field is checked again.  If it is non-zero, then the size of
+  the freed memory is subtracted from the usage, making sure the usage
+  never becomes less than zero.
+
+  This provides adequate accounting with minimal overheads when not in
+  a low memory condition.  When a low memory condition is encountered
+  it does add the cost of a spin lock necessary to serialise updates
+  to 'usage'.
+
+
+
+5/ swapon/swapoff/swap_out/swap_in
+
+  So that a filesystem (e.g. NFS) can know when to set SK_MEMALLOC on
+  any network socket that it uses, and can know when to account
+  reserve memory carefully, new address_space_operations are
+  available.
+  "swapon" requests that an address space (i.e a file) be make ready
+  for swapout.  swap_out and swap_in request the actual IO.  They
+  together must ensure that each swap_out request can succeed without
+  allocating more emergency memory that was reserved by swapon. swapoff
+  is used to reverse the state changes caused by swapon when we disable
+  the swap file.
+
+
+Thanks for reading this far.  I hope it made sense :-)
+
+Neil Brown (with updates from Peter Zijlstra)
-- 
1.7.1.1

--
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

* [PATCH -mmotm 03/30] mm: expose gfp_to_alloc_flags()
From: Xiaotian Feng @ 2010-07-13 10:17 UTC (permalink / raw)
  To: linux-mm, linux-nfs, netdev
  Cc: riel, cl, a.p.zijlstra, Xiaotian Feng, linux-kernel, lwang,
	penberg, akpm, davem
In-Reply-To: <20100713101650.2835.15245.sendpatchset@danny.redhat>

>From 8a554f86ab2fd4d8a1daecaef4cc5bb3901c4423 Mon Sep 17 00:00:00 2001
From: Xiaotian Feng <dfeng@redhat.com>
Date: Mon, 12 Jul 2010 17:59:52 +0800
Subject: [PATCH 03/30] mm: expose gfp_to_alloc_flags()

Expose the gfp to alloc_flags mapping, so we can use it in other parts
of the vm.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
Signed-off-by: Xiaotian Feng <dfeng@redhat.com>
---
 mm/internal.h   |   15 +++++++++++++++
 mm/page_alloc.c |   16 +---------------
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/mm/internal.h b/mm/internal.h
index 6a697bb..3e2cc3a 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -185,6 +185,21 @@ static inline struct page *mem_map_next(struct page *iter,
 #define __paginginit __init
 #endif
 
+/* The ALLOC_WMARK bits are used as an index to zone->watermark */
+#define ALLOC_WMARK_MIN		WMARK_MIN
+#define ALLOC_WMARK_LOW		WMARK_LOW
+#define ALLOC_WMARK_HIGH	WMARK_HIGH
+#define ALLOC_NO_WATERMARKS	0x04 /* don't check watermarks at all */
+
+/* Mask to get the watermark bits */
+#define ALLOC_WMARK_MASK	(ALLOC_NO_WATERMARKS-1)
+
+#define ALLOC_HARDER		0x10 /* try to alloc harder */
+#define ALLOC_HIGH		0x20 /* __GFP_HIGH set */
+#define ALLOC_CPUSET		0x40 /* check for correct cpuset */
+
+int gfp_to_alloc_flags(gfp_t gfp_mask);
+
 /* Memory initialisation debug and verification */
 enum mminit_level {
 	MMINIT_WARNING,
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index ebf0af7..72a6be5 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1345,19 +1345,6 @@ failed:
 	return NULL;
 }
 
-/* The ALLOC_WMARK bits are used as an index to zone->watermark */
-#define ALLOC_WMARK_MIN		WMARK_MIN
-#define ALLOC_WMARK_LOW		WMARK_LOW
-#define ALLOC_WMARK_HIGH	WMARK_HIGH
-#define ALLOC_NO_WATERMARKS	0x04 /* don't check watermarks at all */
-
-/* Mask to get the watermark bits */
-#define ALLOC_WMARK_MASK	(ALLOC_NO_WATERMARKS-1)
-
-#define ALLOC_HARDER		0x10 /* try to alloc harder */
-#define ALLOC_HIGH		0x20 /* __GFP_HIGH set */
-#define ALLOC_CPUSET		0x40 /* check for correct cpuset */
-
 #ifdef CONFIG_FAIL_PAGE_ALLOC
 
 static struct fail_page_alloc_attr {
@@ -1911,8 +1898,7 @@ void wake_all_kswapd(unsigned int order, struct zonelist *zonelist,
 		wakeup_kswapd(zone, order);
 }
 
-static inline int
-gfp_to_alloc_flags(gfp_t gfp_mask)
+int gfp_to_alloc_flags(gfp_t gfp_mask)
 {
 	struct task_struct *p = current;
 	int alloc_flags = ALLOC_WMARK_MIN | ALLOC_CPUSET;
-- 
1.7.1.1

--
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

* [PATCH -mmotm 04/30] mm: tag reseve pages
From: Xiaotian Feng @ 2010-07-13 10:17 UTC (permalink / raw)
  To: linux-mm, linux-nfs, netdev
  Cc: riel, cl, a.p.zijlstra, Xiaotian Feng, linux-kernel, lwang,
	penberg, akpm, davem
In-Reply-To: <20100713101650.2835.15245.sendpatchset@danny.redhat>

>From 14f7823986429b8374d18e3f648cd84575296e03 Mon Sep 17 00:00:00 2001
From: Xiaotian Feng <dfeng@redhat.com>
Date: Mon, 12 Jul 2010 18:00:37 +0800
Subject: [PATCH 04/30] mm: tag reseve pages

Tag pages allocated from the reserves with a non-zero page->reserve.
This allows us to distinguish and account reserve pages.

Since low-memory situations are transient, and unrelated the the actual
page (any page can be on the freelist when we run low), don't mark the
page in any permanent way - just pass along the information to the
allocatee.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
Signed-off-by: Xiaotian Feng <dfeng@redhat.com>
---
 include/linux/mm_types.h |    1 +
 mm/page_alloc.c          |    4 +++-
 2 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index b8bb9a6..a95a202 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -71,6 +71,7 @@ struct page {
 	union {
 		pgoff_t index;		/* Our offset within mapping. */
 		void *freelist;		/* SLUB: freelist req. slab lock */
+		int reserve;		/* page_alloc: page is a reserve page */
 	};
 	struct list_head lru;		/* Pageout list, eg. active_list
 					 * protected by zone->lru_lock !
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 72a6be5..b9989c5 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1656,8 +1656,10 @@ zonelist_scan:
 try_this_zone:
 		page = buffered_rmqueue(preferred_zone, zone, order,
 						gfp_mask, migratetype);
-		if (page)
+		if (page) {
+			page->reserve = !!(alloc_flags & ALLOC_NO_WATERMARKS);
 			break;
+		}
 this_zone_full:
 		if (NUMA_BUILD)
 			zlc_mark_zone_full(zonelist, z);
-- 
1.7.1.1

--
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


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox