Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] netfilter: xtables: userspace notification target
From: Samuel Ortiz @ 2010-07-13 13:28 UTC (permalink / raw)
  To: Changli Gao
  Cc: Patrick McHardy, David S. Miller, netdev, netfilter-devel,
	Luciano Coelho
In-Reply-To: <AANLkTil2EgQbzUqYNHAYpIWJvyyE6AWq1TpvxrqVsD7k@mail.gmail.com>

On Tue, Jul 13, 2010 at 02:18:26PM +0800, 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
> ...
We'd still be missing the possibility of having only the first packet logged,
and we'd have to also send an initial netlink message to switch the copy_mode
to COPY_NONE. We're not interested in the actual packet, but just by the match
hit.
I know it's not big deal after all, I'm just trying to have one simple target
for that simple task of notifying userspace of a match hit.

> > +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.
That's right, I should have used the ATOMIC gfp flags from my sending routine.
I'll fix that with my next revision of the patch.

Thanks for the review.

Cheers,
Samuel.

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

^ permalink raw reply

* High process latencies due to MPC5200 FEC hard- soft-irq processing
From: Wolfgang Grandegger @ 2010-07-13 13:29 UTC (permalink / raw)
  To: Netdev; +Cc: linuxppc-dev@ozlabs.org, LKML

Hello,

we realized, that multiple ping floods (ping -f) can cause very large
high-priority process latencies (up to a many seconds) on a MPC5200
PowerPC system with FEC NAPI support. The latencies are measured with

  # cyclictest -p 80 -n

The problem is that processing of the ICMP pakets in the Hard-Irq and
Soft-IRQ context can last for a long time without returning to the
scheduler. Reducing MAX_SOFTIRQ_RESTART from 10 to 2 helps - the latency
goes down to 35 ms with 2 "ping -f" - but it's not a configurable
parameter, even if it somehow depends on the CPU power. And using the
-rt patches seems overkill to me. Any other ideas or comments on how to
get rid of such high process latencies?

Wolfgang.

^ permalink raw reply

* Re: [PATCH] tc35815: fix iomap leak
From: Atsushi Nemoto @ 2010-07-13 13:14 UTC (permalink / raw)
  To: segooon; +Cc: kernel-janitors, davem, jpirko, eric.dumazet, adobriyan, netdev
In-Reply-To: <1278756199-4636-1-git-send-email-segooon@gmail.com>

On Sat, 10 Jul 2010 14:03:18 +0400, Kulikov Vasiliy <segooon@gmail.com> wrote:
> If tc35815_init_one() fails we must unmap mapped regions.
> 
> Signed-off-by: Kulikov Vasiliy <segooon@gmail.com>
> ---
>  drivers/net/tc35815.c |    4 +++-
>  1 files changed, 3 insertions(+), 1 deletions(-)

No, pcim_xxx APIs are _managed_ interfaces.  These resources are
released automatically.  Actually currently nobody in kernel call
pcim_iounmap_regions() now.

And _if_ there is any reason to call pcim_iounmap_regions()
explicitly, it should be called in tc35815_remove_one() too.

So, NAK.

---
Atsushi Nemoto

^ permalink raw reply

* Re: Splice status
From: Changli Gao @ 2010-07-13 13:58 UTC (permalink / raw)
  To: Ofer Heifetz; +Cc: Eric Dumazet, Jens Axboe, netdev@vger.kernel.org
In-Reply-To: <EE71107DF0D1F24FA2D95041E64AB9E8ED254E7BAB@IL-MB01.marvell.com>

On Tue, Jul 13, 2010 at 8:42 PM, Ofer Heifetz <oferh@marvell.com> wrote:
> Write and re-write numbers are in MBps.
> Iozone performs re-write meaning reads a chunk of data and writes it back, so basically the performance for this operation should be quiet high since kernel caches usage.
>
> I forgot to mention that I used EXT4 fs.

Maybe it is caused by this line in generic_file_splice_write():

                balance_dirty_pages_ratelimited_nr(mapping, nr_pages);

Please try to test it again without this line.

-- 
Regards,
Changli Gao(xiaosuo@gmail.com)

^ permalink raw reply

* RE: Splice status
From: Eric Dumazet @ 2010-07-13 14:11 UTC (permalink / raw)
  To: Ofer Heifetz; +Cc: Changli Gao, Jens Axboe, netdev@vger.kernel.org
In-Reply-To: <EE71107DF0D1F24FA2D95041E64AB9E8ED254E7B66@IL-MB01.marvell.com>

Le mardi 13 juillet 2010 à 14:41 +0300, Ofer Heifetz a écrit :
> Hi,
> 
> I wanted to let you know that I have been testing Samba splice on Marvell 6282 SoC on 2.6.35_rc3 and noticed that it gave worst performance than not using it and also noticed that on re-writing file the iowait is high.
> 
> iometer using 2G file (file is created before test)
> 
> Splice  write cpu% iow%
> -----------------------
>  No     58    98    0
> Yes     14   100   48
> 
> iozone using 2G file (file created during test)
> 
> Splice  write cpu% iow%  re-write cpu% iow%  
> -------------------------------------------
>  No     35    85    4    58.2     70    0
> Yes     33    85    4    15.7    100   58
> 
> Any clue why splice introduces a high iowait?
> I noticed samba uses up to 16K per splice syscall, changing the samba to try more did not help, so I guess it is a kernel limitation.
> 

splice(socket -> pipe) provides partial buffers (depending on the MTU)

With typical MTU=1500 and tcp timestamps, each network frame contains
1448 bytes of payload, partially filling one page (of 4096 bytes)

When doing the splice(pipe -> file), kernel has to coalesce partial
data, but amount of written data per syscall() is small (about 20
Kbytes)

Without splice(), the write() syscall provides more data, and vfs
overhead is smaller as buffer size is a power of two.

Samba uses a 128 KBytes TRANSFER_BUF_SIZE in its default_sys_recvfile()
implementation, it easily outperforms splice() implementation.

You could try extending pipe size (fcntl(fd, F_SETPIPE_SZ, 256)), maybe
it will be a bit better. (and ask 256*4096 bytes to splice())

I tried this and got about 256Kbytes per splice() call...

# perf report
# Events: 13K
#
# Overhead         Command      Shared Object  Symbol
# ........  ..............  .................  ......
#
     8.69%  splice-fromnet  [kernel.kallsyms]  [k] memcpy
     3.82%  splice-fromnet  [kernel.kallsyms]  [k] kunmap_atomic
     3.51%  splice-fromnet  [kernel.kallsyms]  [k] __block_prepare_write
     2.79%  splice-fromnet  [kernel.kallsyms]  [k] __skb_splice_bits
     2.58%  splice-fromnet  [kernel.kallsyms]  [k] ext3_mark_iloc_dirty
     2.45%  splice-fromnet  [kernel.kallsyms]  [k] do_get_write_access
     2.04%  splice-fromnet  [kernel.kallsyms]  [k] __find_get_block
     1.89%  splice-fromnet  [kernel.kallsyms]  [k] _raw_spin_lock
     1.83%  splice-fromnet  [kernel.kallsyms]  [k] journal_add_journal_head
     1.46%  splice-fromnet  [bnx2x]            [k] bnx2x_rx_int
     1.46%  splice-fromnet  [kernel.kallsyms]  [k] kfree
     1.42%  splice-fromnet  [kernel.kallsyms]  [k] journal_put_journal_head
     1.29%  splice-fromnet  [kernel.kallsyms]  [k] __ext3_get_inode_loc
     1.26%  splice-fromnet  [kernel.kallsyms]  [k] journal_dirty_metadata
     1.25%  splice-fromnet  [kernel.kallsyms]  [k] page_address
     1.20%  splice-fromnet  [kernel.kallsyms]  [k] journal_cancel_revoke
     1.15%  splice-fromnet  [kernel.kallsyms]  [k] tcp_read_sock
     1.09%  splice-fromnet  [kernel.kallsyms]  [k] unlock_buffer
     1.09%  splice-fromnet  [kernel.kallsyms]  [k] pipe_to_file
     1.05%  splice-fromnet  [kernel.kallsyms]  [k] radix_tree_lookup_element
     1.04%  splice-fromnet  [kernel.kallsyms]  [k] kmap_atomic_prot
     1.04%  splice-fromnet  [kernel.kallsyms]  [k] kmem_cache_free
     1.03%  splice-fromnet  [kernel.kallsyms]  [k] kmem_cache_alloc
     1.01%  splice-fromnet  [bnx2x]            [k] bnx2x_poll



^ permalink raw reply

* Re: [PATCH] tproxy: nf_tproxy_assign_sock() can handle tw sockets
From: Felipe W Damasio @ 2010-07-13 14:24 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Avi Kivity, David Miller, Patrick McHardy, linux-kernel, netdev
In-Reply-To: <AANLkTilbEkJWPqvJE72r9HdFQSU84S02BKZB0CH-8QwB@mail.gmail.com>

Hi Mr. Dumazet,

2010/7/12 Felipe W Damasio <felipewd@gmail.com>:
> Here's the result using ethtool-2.6.34:
>
> ./ethtool -k eth1
>
> Offload parameters for eth1:
> rx-checksumming: on
> tx-checksumming: on
> scatter-gather: on
> tcp-segmentation-offload: on
> udp-fragmentation-offload: off
> generic-segmentation-offload: on
> generic-receive-offload: off
> large-receive-offload: off
> ntuple-filters: off
> receive-hashing: off
>
>
> ./ethtool -k eth2
>
> Offload parameters for eth2:
> rx-checksumming: on
> tx-checksumming: on
> scatter-gather: on
> tcp-segmentation-offload: on
> udp-fragmentation-offload: off
> generic-segmentation-offload: on
> generic-receive-offload: off
> large-receive-offload: off
> ntuple-filters: off
> receive-hashing: off

Did these help you track down the issue?

Sorry to insist, it's just that my bosses are kind of pressuring me to
solve the problem and put the squid machine back online :-)

Is there a test I can run to try and trigger the issue?

I have the same scenario (hardware and network setup) on my lab...

Cheers,

Felipe Damasio

^ permalink raw reply

* Re: [PATCH] tproxy: nf_tproxy_assign_sock() can handle tw sockets
From: Eric Dumazet @ 2010-07-13 14:40 UTC (permalink / raw)
  To: Felipe W Damasio
  Cc: Avi Kivity, David Miller, Patrick McHardy, linux-kernel, netdev
In-Reply-To: <AANLkTimn9x17g-4K7fS4MjmCgzHuBARurEoFVd_gId7m@mail.gmail.com>

Le mardi 13 juillet 2010 à 11:24 -0300, Felipe W Damasio a écrit :
> Hi Mr. Dumazet,
> 
> 2010/7/12 Felipe W Damasio <felipewd@gmail.com>:
> > Here's the result using ethtool-2.6.34:
> >
> > ./ethtool -k eth1
> >
> > Offload parameters for eth1:
> > rx-checksumming: on
> > tx-checksumming: on
> > scatter-gather: on
> > tcp-segmentation-offload: on
> > udp-fragmentation-offload: off
> > generic-segmentation-offload: on
> > generic-receive-offload: off
> > large-receive-offload: off
> > ntuple-filters: off
> > receive-hashing: off
> >
> >
> > ./ethtool -k eth2
> >
> > Offload parameters for eth2:
> > rx-checksumming: on
> > tx-checksumming: on
> > scatter-gather: on
> > tcp-segmentation-offload: on
> > udp-fragmentation-offload: off
> > generic-segmentation-offload: on
> > generic-receive-offload: off
> > large-receive-offload: off
> > ntuple-filters: off
> > receive-hashing: off
> 
> Did these help you track down the issue?
> 
> Sorry to insist, it's just that my bosses are kind of pressuring me to
> solve the problem and put the squid machine back online :-)
> 
> Is there a test I can run to try and trigger the issue?
> 
> I have the same scenario (hardware and network setup) on my lab...
> 

I currently have no fresh ideas. If you want this problem to be solved,
its important to setup in your lab a workload to trigger again and again
the bug, in order to provide us more crash information.

After code review doesnt spot obvious bugs, this is time for brute force
hunting, using git bisection for example...




^ permalink raw reply

* RE: Splice status
From: Ofer Heifetz @ 2010-07-13 14:40 UTC (permalink / raw)
  To: Changli Gao; +Cc: Eric Dumazet, Jens Axboe, netdev@vger.kernel.org
In-Reply-To: <AANLkTimZyIhl34NzAZXMNUEmGy0KFCBs_LMk5qSBwrF2@mail.gmail.com>

I profiled the splice iometer write run and noticed that blk_end_request_err is being called many times, it looks like a good candidate for the high iowait, need to debug the root cause for it.

-Ofer

-----Original Message-----
From: Changli Gao [mailto:xiaosuo@gmail.com] 
Sent: Tuesday, July 13, 2010 4:58 PM
To: Ofer Heifetz
Cc: Eric Dumazet; Jens Axboe; netdev@vger.kernel.org
Subject: Re: Splice status

On Tue, Jul 13, 2010 at 8:42 PM, Ofer Heifetz <oferh@marvell.com> wrote:
> Write and re-write numbers are in MBps.
> Iozone performs re-write meaning reads a chunk of data and writes it back, so basically the performance for this operation should be quiet high since kernel caches usage.
>
> I forgot to mention that I used EXT4 fs.

Maybe it is caused by this line in generic_file_splice_write():

                balance_dirty_pages_ratelimited_nr(mapping, nr_pages);

Please try to test it again without this line.

-- 
Regards,
Changli Gao(xiaosuo@gmail.com)

^ permalink raw reply

* Re: [PATCH] tproxy: nf_tproxy_assign_sock() can handle tw sockets
From: Felipe W Damasio @ 2010-07-13 14:49 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Avi Kivity, David Miller, Patrick McHardy, linux-kernel, netdev
In-Reply-To: <1279032023.2634.384.camel@edumazet-laptop>

Hi Mr. Dumazet,

2010/7/13 Eric Dumazet <eric.dumazet@gmail.com>:
> I currently have no fresh ideas. If you want this problem to be solved,
> its important to setup in your lab a workload to trigger again and again
> the bug, in order to provide us more crash information.

 Right. I've been running non-stop since the first bug happened, but
so far the problem hasn't surfaced again :-(

 I've been using the kernel with the patch that you provided me
(nf_tproxy.c). Is there a chance that patch fixed the problem?

 Cheers,

Felipe Damasio

^ permalink raw reply

* [PATCH v2] netfilter: xtables: userspace notification target
From: Samuel Ortiz @ 2010-07-13 14:57 UTC (permalink / raw)
  To: Patrick McHardy, David S. Miller
  Cc: netdev, netfilter-devel, Luciano Coelho, sameo, Jan Engelhardt,
	Changli Gao, Pablo Neira Ayuso
In-Reply-To: <20100713001115.GA3751@sortiz-mobl>


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.

Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
v2:
- Remove the work structure and make the netlink sending routine atomic.
- Reformat struct nfnotif_tg to get rid of unnecessary padding holes.
---
 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                 |  287 ++++++++++++++++++++++++++++
 7 files changed, 366 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..75ddeba
--- /dev/null
+++ b/net/netfilter/xt_NFNOTIF.c
@@ -0,0 +1,287 @@
+/*
+ * 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;
+
+	char *label;
+	struct net *net;
+	unsigned int refcnt;
+	__u8 all_packets;
+	__u8 send_notif;
+};
+
+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_ATOMIC);
+	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_ATOMIC);
+
+nla_put_failure:
+	nlmsg_cancel(skb, nlh);
+
+nlmsg_put_failure:
+	kfree_skb(skb);
+
+error_out:
+	return nfnetlink_set_err(net, 0, 0, -ENOBUFS);
+}
+
+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;
+
+	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);
+
+	if (__nfnotif_tg_netlink_send(info->notif) < 0)
+		pr_debug("Could not send notification");
+
+	if (!info->notif->all_packets)
+		info->notif->send_notif = 0;
+
+	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/

^ permalink raw reply related

* [PATCH net-next-2.6] net/core: neighbour update Oops
From: Doug Kehn @ 2010-07-13 15:23 UTC (permalink / raw)
  To: davem; +Cc: netdev, eric.dumazet

When configuring DMVPN (GRE + openNHRP) and a GRE remote
address is configured a kernel Oops is observed.  The
obserseved Oops is caused by a NULL header_ops pointer
(neigh->dev->header_ops) in neigh_update_hhs() when

void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *)
= neigh->dev->header_ops->cache_update;

is executed.  The dev associated with the NULL header_ops is
the GRE interface.  This patch guards against the
possibility that header_ops is NULL.

This Oops was first observed in kernel version 2.6.26.8.

Signed-off-by: Doug Kehn <rdkehn@yahoo.com>
---
 net/core/neighbour.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 6ba1c0e..a4e0a74 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -949,7 +949,10 @@ static void neigh_update_hhs(struct neighbour *neigh)
 {
 	struct hh_cache *hh;
 	void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *)
-		= neigh->dev->header_ops->cache_update;
+		= NULL;
+
+	if (neigh->dev->header_ops)
+		update = neigh->dev->header_ops->cache_update;
 
 	if (update) {
 		for (hh = neigh->hh; hh; hh = hh->hh_next) {
-- 
1.7.0.4



      

^ permalink raw reply related

* [PATCH] net: skb_tx_hash() fix relative to skb_orphan_try()
From: Eric Dumazet @ 2010-07-13 15:24 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

commit fc6055a5ba31e2 (net: Introduce skb_orphan_try()) added early
orphaning of skbs.

This unfortunately added a performance regression in skb_tx_hash() in
case of stacked devices (bonding, vlans, ...)

Since skb->sk is now NULL, we cannot access sk->sk_hash anymore to
spread tx packets to multiple NIC queues on multiqueue devices.

skb_tx_hash() in this case only uses skb->protocol, same value for all
flows.

skb_orphan_try() can copy sk->sk_hash into skb->rxhash and skb_tx_hash()
can use this saved sk_hash value to compute its internal hash value.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 net/core/dev.c |   13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 723a347..70a900a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1911,8 +1911,16 @@ static int dev_gso_segment(struct sk_buff *skb)
  */
 static inline void skb_orphan_try(struct sk_buff *skb)
 {
-	if (!skb_tx(skb)->flags)
+	struct sock *sk = skb->sk;
+
+	if (sk && !skb_tx(skb)->flags) {
+		/* skb_tx_hash() wont be able to get sk.
+		 * We copy sk_hash into skb->rxhash
+		 */ 
+		if (!skb->rxhash)
+			skb->rxhash = sk->sk_hash;
 		skb_orphan(skb);
+	}
 }
 
 int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
@@ -1998,8 +2006,7 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb)
 	if (skb->sk && skb->sk->sk_hash)
 		hash = skb->sk->sk_hash;
 	else
-		hash = (__force u16) skb->protocol;
-
+		hash = (__force u16) skb->protocol ^ skb->rxhash;
 	hash = jhash_1word(hash, hashrnd);
 
 	return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32);




^ permalink raw reply related

* Re: [PATCH net-next-2.6] net/core: neighbour update Oops
From: Eric Dumazet @ 2010-07-13 15:38 UTC (permalink / raw)
  To: Doug Kehn; +Cc: davem, netdev
In-Reply-To: <734423.1943.qm@web52004.mail.re2.yahoo.com>

Le mardi 13 juillet 2010 à 08:23 -0700, Doug Kehn a écrit :
> When configuring DMVPN (GRE + openNHRP) and a GRE remote
> address is configured a kernel Oops is observed.  The
> obserseved Oops is caused by a NULL header_ops pointer
> (neigh->dev->header_ops) in neigh_update_hhs() when
> 
> void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *)
> = neigh->dev->header_ops->cache_update;
> 
> is executed.  The dev associated with the NULL header_ops is
> the GRE interface.  This patch guards against the
> possibility that header_ops is NULL.
> 
> This Oops was first observed in kernel version 2.6.26.8.
> 
> Signed-off-by: Doug Kehn <rdkehn@yahoo.com>

Acked-by: Eric Dumazet <eric.dumazet@gmail.com>

> ---
>  net/core/neighbour.c |    5 ++++-
>  1 files changed, 4 insertions(+), 1 deletions(-)
> 
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index 6ba1c0e..a4e0a74 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -949,7 +949,10 @@ static void neigh_update_hhs(struct neighbour *neigh)
>  {
>  	struct hh_cache *hh;
>  	void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *)
> -		= neigh->dev->header_ops->cache_update;
> +		= NULL;
> +
> +	if (neigh->dev->header_ops)
> +		update = neigh->dev->header_ops->cache_update;
>  
>  	if (update) {
>  		for (hh = neigh->hh; hh; hh = hh->hh_next) {



^ permalink raw reply

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

On Mon, 12 Jul 2010 22:32:53 -0700
Ben Greear <greearb@candelatech.com> wrote:

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

I am going to put a more restrictive version of getcmdline().  Comments
will only be allowed at start of line.

^ permalink raw reply

* [PATCH v4 2.6.35-rc3] drivers/net: ks8842 driver
From: Choi, David @ 2010-07-13 15:42 UTC (permalink / raw)
  To: netdev; +Cc: davem, Li, Charles, horms

Hi David & Simon and all,

Sorry for bothering you by sending this patch in HTML format.

It seems that there are differences between Micrel ks8842 device and Timberdale
FPGA based device with generic bus interface. In order to check the differences,
I have sent several times but have not received any response. This patch is to 
support ks8841/ks8842 device from Micrel.

From: David J. Choi <david.choi@micrel.com>

Body of the explanation: 
   -support 16bit and 32bit bus width.
   -add device reset for ks8842/8841 Micrel device.
   -set 100Mbps as a default for Micrel device.
   -set MAC address in both MAC/Switch layer with different sequence for Micrel
    device, as mentioned in data sheet.
   -use private data to set options both 16/32bit bus width and Micrel device/
    Timberdale(FPGA).
   -update Kconfig in order to put more information about ks8842 device.

Signed-off-by: David J. Choi <david.choi@micrel.com>

---
--- linux-2.6.35-rc3/drivers/net/ks8842.c.orig	2010-07-01 16:26:50.000000000 -0700
+++ linux-2.6.35-rc3/drivers/net/ks8842.c	2010-07-09 13:27:37.000000000 -0700
@@ -18,6 +18,7 @@
 
 /* Supports:
  * The Micrel KS8842 behind the timberdale FPGA
+ * The genuine Micrel KS8841/42 device with ISA 16/32bit bus interface
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -114,9 +115,14 @@
 #define REG_P1CR4		0x02
 #define REG_P1SR		0x04
 
+/* flags passed by platform_device for configuration */
+#define	MICREL_KS884X		0x01	/* 0=Timeberdale(FPGA), 1=Micrel */
+#define	KS884X_16BIT		0x02	/*  1=16bit, 0=32bit */
+
 struct ks8842_adapter {
 	void __iomem	*hw_addr;
 	int		irq;
+	unsigned long	conf_flags;	/* copy of platform_device config */
 	struct tasklet_struct	tasklet;
 	spinlock_t	lock; /* spinlock to be interrupt safe */
 	struct platform_device *pdev;
@@ -191,16 +197,22 @@ static inline u32 ks8842_read32(struct k
 
 static void ks8842_reset(struct ks8842_adapter *adapter)
 {
-	/* The KS8842 goes haywire when doing softare reset
-	 * a work around in the timberdale IP is implemented to
-	 * do a hardware reset instead
-	ks8842_write16(adapter, 3, 1, REG_GRR);
-	msleep(10);
-	iowrite16(0, adapter->hw_addr + REG_GRR);
-	*/
-	iowrite16(32, adapter->hw_addr + REG_SELECT_BANK);
-	iowrite32(0x1, adapter->hw_addr + REG_TIMB_RST);
-	msleep(20);
+	if (adapter->conf_flags & MICREL_KS884X) {
+		ks8842_write16(adapter, 3, 1, REG_GRR);
+		msleep(10);
+		iowrite16(0, adapter->hw_addr + REG_GRR);
+	} else {
+		/* The KS8842 goes haywire when doing softare reset
+		* a work around in the timberdale IP is implemented to
+		* do a hardware reset instead
+		ks8842_write16(adapter, 3, 1, REG_GRR);
+		msleep(10);
+		iowrite16(0, adapter->hw_addr + REG_GRR);
+		*/
+		iowrite16(32, adapter->hw_addr + REG_SELECT_BANK);
+		iowrite32(0x1, adapter->hw_addr + REG_TIMB_RST);
+		msleep(20);
+	}
 }
 
 static void ks8842_update_link_status(struct net_device *netdev,
@@ -269,8 +281,10 @@ static void ks8842_reset_hw(struct ks884
 
 	/* restart port auto-negotiation */
 	ks8842_enable_bits(adapter, 49, 1 << 13, REG_P1CR4);
-	/* only advertise 10Mbps */
-	ks8842_clear_bits(adapter, 49, 3 << 2, REG_P1CR4);
+
+	if (!(adapter->conf_flags & MICREL_KS884X))
+		/* only advertise 10Mbps */
+		ks8842_clear_bits(adapter, 49, 3 << 2, REG_P1CR4);
 
 	/* Enable the transmitter */
 	ks8842_enable_tx(adapter);
@@ -296,13 +310,28 @@ static void ks8842_read_mac_addr(struct 
 	for (i = 0; i < ETH_ALEN; i++)
 		dest[ETH_ALEN - i - 1] = ks8842_read8(adapter, 2, REG_MARL + i);
 
-	/* make sure the switch port uses the same MAC as the QMU */
-	mac = ks8842_read16(adapter, 2, REG_MARL);
-	ks8842_write16(adapter, 39, mac, REG_MACAR1);
-	mac = ks8842_read16(adapter, 2, REG_MARM);
-	ks8842_write16(adapter, 39, mac, REG_MACAR2);
-	mac = ks8842_read16(adapter, 2, REG_MARH);
-	ks8842_write16(adapter, 39, mac, REG_MACAR3);
+	if (adapter->conf_flags & MICREL_KS884X) {
+		/*
+		the sequence of saving mac addr between MAC and Switch is
+		different.
+		*/
+
+		mac = ks8842_read16(adapter, 2, REG_MARL);
+		ks8842_write16(adapter, 39, mac, REG_MACAR3);
+		mac = ks8842_read16(adapter, 2, REG_MARM);
+		ks8842_write16(adapter, 39, mac, REG_MACAR2);
+		mac = ks8842_read16(adapter, 2, REG_MARH);
+		ks8842_write16(adapter, 39, mac, REG_MACAR1);
+	} else {
+
+		/* make sure the switch port uses the same MAC as the QMU */
+		mac = ks8842_read16(adapter, 2, REG_MARL);
+		ks8842_write16(adapter, 39, mac, REG_MACAR1);
+		mac = ks8842_read16(adapter, 2, REG_MARM);
+		ks8842_write16(adapter, 39, mac, REG_MACAR2);
+		mac = ks8842_read16(adapter, 2, REG_MARH);
+		ks8842_write16(adapter, 39, mac, REG_MACAR3);
+	}
 }
 
 static void ks8842_write_mac_addr(struct ks8842_adapter *adapter, u8 *mac)
@@ -313,8 +342,25 @@ static void ks8842_write_mac_addr(struct
 	spin_lock_irqsave(&adapter->lock, flags);
 	for (i = 0; i < ETH_ALEN; i++) {
 		ks8842_write8(adapter, 2, mac[ETH_ALEN - i - 1], REG_MARL + i);
-		ks8842_write8(adapter, 39, mac[ETH_ALEN - i - 1],
-			REG_MACAR1 + i);
+		if (!(adapter->conf_flags & MICREL_KS884X))
+			ks8842_write8(adapter, 39, mac[ETH_ALEN - i - 1],
+				REG_MACAR1 + i);
+	}
+
+	if (adapter->conf_flags & MICREL_KS884X) {
+		/*
+		the sequence of saving mac addr between MAC and Switch is
+		different.
+		*/
+
+		u16 mac;
+
+		mac = ks8842_read16(adapter, 2, REG_MARL);
+		ks8842_write16(adapter, 39, mac, REG_MACAR3);
+		mac = ks8842_read16(adapter, 2, REG_MARM);
+		ks8842_write16(adapter, 39, mac, REG_MACAR2);
+		mac = ks8842_read16(adapter, 2, REG_MARH);
+		ks8842_write16(adapter, 39, mac, REG_MACAR1);
 	}
 	spin_unlock_irqrestore(&adapter->lock, flags);
 }
@@ -328,8 +374,6 @@ static int ks8842_tx_frame(struct sk_buf
 {
 	struct ks8842_adapter *adapter = netdev_priv(netdev);
 	int len = skb->len;
-	u32 *ptr = (u32 *)skb->data;
-	u32 ctrl;
 
 	dev_dbg(&adapter->pdev->dev,
 		"%s: len %u head %p data %p tail %p end %p\n",
@@ -340,17 +384,34 @@ static int ks8842_tx_frame(struct sk_buf
 	if (ks8842_tx_fifo_space(adapter) < len + 8)
 		return NETDEV_TX_BUSY;
 
-	/* the control word, enable IRQ, port 1 and the length */
-	ctrl = 0x8000 | 0x100 | (len << 16);
-	ks8842_write32(adapter, 17, ctrl, REG_QMU_DATA_LO);
-
-	netdev->stats.tx_bytes += len;
-
-	/* copy buffer */
-	while (len > 0) {
-		iowrite32(*ptr, adapter->hw_addr + REG_QMU_DATA_LO);
-		len -= sizeof(u32);
-		ptr++;
+	if (adapter->conf_flags & KS884X_16BIT) {
+		u16 *ptr16 = (u16 *)skb->data;
+		ks8842_write16(adapter, 17, 0x8000 | 0x100, REG_QMU_DATA_LO);
+		ks8842_write16(adapter, 17, (u16)len, REG_QMU_DATA_HI);
+		netdev->stats.tx_bytes += len;
+
+		/* copy buffer */
+		while (len > 0) {
+			iowrite16(*ptr16++, adapter->hw_addr + REG_QMU_DATA_LO);
+			iowrite16(*ptr16++, adapter->hw_addr + REG_QMU_DATA_HI);
+			len -= sizeof(u32);
+		}
+	} else {
+
+		u32 *ptr = (u32 *)skb->data;
+		u32 ctrl;
+		/* the control word, enable IRQ, port 1 and the length */
+		ctrl = 0x8000 | 0x100 | (len << 16);
+		ks8842_write32(adapter, 17, ctrl, REG_QMU_DATA_LO);
+
+		netdev->stats.tx_bytes += len;
+
+		/* copy buffer */
+		while (len > 0) {
+			iowrite32(*ptr, adapter->hw_addr + REG_QMU_DATA_LO);
+			len -= sizeof(u32);
+			ptr++;
+		}
 	}
 
 	/* enqueue packet */
@@ -364,13 +425,23 @@ static int ks8842_tx_frame(struct sk_buf
 static void ks8842_rx_frame(struct net_device *netdev,
 	struct ks8842_adapter *adapter)
 {
-	u32 status = ks8842_read32(adapter, 17, REG_QMU_DATA_LO);
-	int len = (status >> 16) & 0x7ff;
-
-	status &= 0xffff;
-
-	dev_dbg(&adapter->pdev->dev, "%s - rx_data: status: %x\n",
-		__func__, status);
+	u16 status16;
+	u32 status;
+	int len;
+
+	if (adapter->conf_flags & KS884X_16BIT) {
+		status16 = ks8842_read16(adapter, 17, REG_QMU_DATA_LO);
+		len  = (int)ks8842_read16(adapter, 17, REG_QMU_DATA_HI);
+		len &= 0xffff;
+		dev_dbg(&adapter->pdev->dev, "%s - rx_data: status: %x\n",
+			__func__, status16);
+	} else {
+		status = ks8842_read32(adapter, 17, REG_QMU_DATA_LO);
+		len = (status >> 16) & 0x7ff;
+		status &= 0xffff;
+		dev_dbg(&adapter->pdev->dev, "%s - rx_data: status: %x\n",
+			__func__, status);
+	}
 
 	/* check the status */
 	if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) {
@@ -379,22 +450,32 @@ static void ks8842_rx_frame(struct net_d
 		dev_dbg(&adapter->pdev->dev, "%s, got package, len: %d\n",
 			__func__, len);
 		if (skb) {
-			u32 *data;
 
 			netdev->stats.rx_packets++;
 			netdev->stats.rx_bytes += len;
 			if (status & RXSR_MULTICAST)
 				netdev->stats.multicast++;
 
-			data = (u32 *)skb_put(skb, len);
-
-			ks8842_select_bank(adapter, 17);
-			while (len > 0) {
-				*data++ = ioread32(adapter->hw_addr +
-					REG_QMU_DATA_LO);
-				len -= sizeof(u32);
+			if (adapter->conf_flags & KS884X_16BIT) {
+				u16 *data16 = (u16 *)skb_put(skb, len);
+				ks8842_select_bank(adapter, 17);
+				while (len > 0) {
+					*data16++ = ioread16(adapter->hw_addr +
+						REG_QMU_DATA_LO);
+					*data16++ = ioread16(adapter->hw_addr +
+						REG_QMU_DATA_HI);
+					len -= sizeof(u32);
+				}
+			} else {
+				u32 *data = (u32 *)skb_put(skb, len);
+
+				ks8842_select_bank(adapter, 17);
+				while (len > 0) {
+					*data++ = ioread32(adapter->hw_addr +
+						REG_QMU_DATA_LO);
+					len -= sizeof(u32);
+				}
 			}
-
 			skb->protocol = eth_type_trans(skb, netdev);
 			netif_rx(skb);
 		} else
@@ -654,6 +735,8 @@ static int __devinit ks8842_probe(struct
 
 	adapter = netdev_priv(netdev);
 	adapter->hw_addr = ioremap(iomem->start, resource_size(iomem));
+	adapter->conf_flags = iomem->flags;
+
 	if (!adapter->hw_addr)
 		goto err_ioremap;
 
--- linux-2.6.35-rc3/drivers/net/Kconfig.orig	2010-07-02 15:52:41.000000000 -0700
+++ linux-2.6.35-rc3/drivers/net/Kconfig	2010-07-09 13:33:56.000000000 -0700
@@ -1748,11 +1748,12 @@ config TLAN
 	  Please email feedback to <torben.mathiasen@compaq.com>.
 
 config KS8842
-	tristate "Micrel KSZ8842"
+	tristate "Micrel KSZ8841/42 with generic bus interface"
 	depends on HAS_IOMEM
 	help
-	  This platform driver is for Micrel KSZ8842 / KS8842
-	  2-port ethernet switch chip (managed, VLAN, QoS).
+	 This platform driver is for KSZ8841(1-port) / KS8842(2-port)
+	 ethernet switch chip (managed, VLAN, QoS) from Micrel or
+	 Timberdale(FPGA).
 
 config KS8851
        tristate "Micrel KS8851 SPI"

---


^ permalink raw reply

* Re: [PATCH] tproxy: nf_tproxy_assign_sock() can handle tw sockets
From: Eric Dumazet @ 2010-07-13 15:49 UTC (permalink / raw)
  To: Felipe W Damasio
  Cc: Avi Kivity, David Miller, Patrick McHardy, linux-kernel, netdev
In-Reply-To: <AANLkTilrIByt4xAHhsBsKo3nDfv0_c3sF-dCiTiYiPnu@mail.gmail.com>

Le mardi 13 juillet 2010 à 11:49 -0300, Felipe W Damasio a écrit :
> Hi Mr. Dumazet,
> 
> 2010/7/13 Eric Dumazet <eric.dumazet@gmail.com>:
> > I currently have no fresh ideas. If you want this problem to be solved,
> > its important to setup in your lab a workload to trigger again and again
> > the bug, in order to provide us more crash information.
> 
>  Right. I've been running non-stop since the first bug happened, but
> so far the problem hasn't surfaced again :-(
> 
>  I've been using the kernel with the patch that you provided me
> (nf_tproxy.c). Is there a chance that patch fixed the problem?

This is a real bug, but I dont think it can fix your problem.

Looking again at your crash, we see RCX=0x720, decimal 1824

As its skb->len, we are freeing an skb that was collapsed or something
like that, since 1824 > 1460 (the normal MSS on ethernet)

GRO is off on your machine.

But coincidently 0x0720 is also a blank char for VGA screen...
(0x20 : ASCII space, 0x07 : default attribute)

So maybe you hit a corruption outside of network stack.

^ permalink raw reply

* Re: [patch] net/sched: potential data corruption
From: jamal @ 2010-07-13 15:58 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: David S. Miller, Stephen Hemminger, netdev, kernel-janitors,
	matthew
In-Reply-To: <20100713132152.GL5658@bicker>

On Tue, 2010-07-13 at 15:21 +0200, Dan Carpenter wrote:
> The reset_policy() does:
>         memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
>         strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
> 
> In the original code, the size of d->tcfd_defdata wasn't fixed and if
> strlen(defdata) was less than 31, reset_policy() would cause memory
> corruption.
> 
> Please Note:  The original alloc_defdata() assumes defdata is 32
> characters and a NUL terminator while reset_policy() assumes defdata is
> 31 characters and a NUL.  This patch updates alloc_defdata() to match
> reset_policy() (ie a shorter string).  I'm not very familiar with this
> code so please review carefully.
> 
> Signed-off-by: Dan Carpenter <error27@gmail.com>


Acked-by: Jamal Hadi Salim <hadi@cyberus.ca>


cheers,
jamal


^ permalink raw reply

* Re: [PATCH] netfilter: xtables: userspace notification target
From: Pablo Neira Ayuso @ 2010-07-13 16:38 UTC (permalink / raw)
  To: Luciano Coelho
  Cc: Changli Gao, Samuel Ortiz, Patrick McHardy, David S. Miller,
	netdev@vger.kernel.org, netfilter-devel@vger.kernel.org
In-Reply-To: <1279016596.12673.11.camel@chilepepper>

On 13/07/10 12:23, Luciano Coelho wrote:
> On Tue, 2010-07-13 at 10:50 +0200, ext Pablo Neira Ayuso wrote:
>> 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.
>
> Is it possible to have the NFLOG send only one notification to the
> userspace?

Not possible, but you could easily extend NFLOG to implement this 
feature if it's not possible to do what you need with the existing 
matches/targets. This NOTIF infrastructure is redundant and it looks 
like a subset of NFLOG.

There's a padding field in xt_NFLOG that is currently unused, it could 
be used for this.

Or we could add some 'count' match to store the number of packets that 
have matched a rule (although not sure if this is generic enough to be 
useful for others).

> In the example above, once the quota exceeds, the userspace
> will be notified of every packet arriving, won't it?  That would cause
> unnecessary processing in the userspace.
>
> The userspace could remove the rule when it gets the first notification
> and only add it again when it needs to get the information again (as a
> "toggle" functionality), but I think that would take too long and there
> would be several packets going through before the rule could be removed.

You can do that with libnetfilter_log to handle the log messages 
received and the minor change for xt_NFLOG that I proposed.

^ permalink raw reply

* Re: [PATCH net-next-2.6]  macvtap: Return error when macvlan drops the packet
From: Shirley Ma @ 2010-07-13 16:42 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: sri, netdev, davem
In-Reply-To: <201007121244.04499.arnd@arndb.de>

Hello Arnd,

I am working on macvtap zero-copy patch. I found that the packet was
silently dropped and packet out of order when using zero-copy. That was
a reason I submitted this patch to switch to copy mode when that
happens. I think I might need more time to debug why first.

Thanks
Shirley


^ permalink raw reply

* Re: [PATCH v4 2.6.35-rc3] drivers/net: ks8842 driver
From: David Miller @ 2010-07-13 17:14 UTC (permalink / raw)
  To: David.Choi; +Cc: netdev, Charles.Li, horms
In-Reply-To: <C43529A246480145B0A6D0234BDB0F0D0212A7@MELANITE.micrel.com>

From: "Choi, David" <David.Choi@Micrel.Com>
Date: Tue, 13 Jul 2010 08:42:41 -0700

> From: David J. Choi <david.choi@micrel.com>
> 
> Body of the explanation: 
>    -support 16bit and 32bit bus width.
>    -add device reset for ks8842/8841 Micrel device.
>    -set 100Mbps as a default for Micrel device.
>    -set MAC address in both MAC/Switch layer with different sequence for Micrel
>     device, as mentioned in data sheet.
>    -use private data to set options both 16/32bit bus width and Micrel device/
>     Timberdale(FPGA).
>    -update Kconfig in order to put more information about ks8842 device.
> 
> Signed-off-by: David J. Choi <david.choi@micrel.com>

This patch doesn't apply to net-next-2.6 because the bank select I/O
write has been removed from the reset function, and the driver now
uses netdev_*() instead of dev_*() logging functions.

Also, your patch subject line should be more descriptive, it doesn't
say what this patch is doing, it just says "ks8842 driver", well this
driver already supports ks8842 chips just not "Micrel KS8842/8841"
ones.  So I changed the subject line to describe what this patch is
actually doing.

Also, when you want to make side-commentary to us which is not meant
to go into the commit, place it after the commit message (not before),
seperated from the commit message with "---" on a line by itself.

I fixed all of this up and applied your patch as follows:

--------------------
>From 28bd620c7a1244e59459d6293ca11f162e0a67b9 Mon Sep 17 00:00:00 2001
From: David J. Choi <david.choi@micrel.com>
Date: Tue, 13 Jul 2010 10:09:19 -0700
Subject: [PATCH] drivers/net: Add Micrel KS8841/42 support to ks8842 driver

Body of the explanation:
   -support 16bit and 32bit bus width.
   -add device reset for ks8842/8841 Micrel device.
   -set 100Mbps as a default for Micrel device.
   -set MAC address in both MAC/Switch layer with different sequence for Micrel
    device, as mentioned in data sheet.
   -use private data to set options both 16/32bit bus width and Micrel device/
    Timberdale(FPGA).
   -update Kconfig in order to put more information about ks8842 device.

Signed-off-by: David J. Choi <david.choi@micrel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/Kconfig  |    7 +-
 drivers/net/ks8842.c |  174 +++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 133 insertions(+), 48 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index f65857e..8829476 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1750,11 +1750,12 @@ config TLAN
 	  Please email feedback to <torben.mathiasen@compaq.com>.
 
 config KS8842
-	tristate "Micrel KSZ8842"
+	tristate "Micrel KSZ8841/42 with generic bus interface"
 	depends on HAS_IOMEM
 	help
-	  This platform driver is for Micrel KSZ8842 / KS8842
-	  2-port ethernet switch chip (managed, VLAN, QoS).
+	 This platform driver is for KSZ8841(1-port) / KS8842(2-port)
+	 ethernet switch chip (managed, VLAN, QoS) from Micrel or
+	 Timberdale(FPGA).
 
 config KS8851
        tristate "Micrel KS8851 SPI"
diff --git a/drivers/net/ks8842.c b/drivers/net/ks8842.c
index 0be9261..ee69dea 100644
--- a/drivers/net/ks8842.c
+++ b/drivers/net/ks8842.c
@@ -18,6 +18,7 @@
 
 /* Supports:
  * The Micrel KS8842 behind the timberdale FPGA
+ * The genuine Micrel KS8841/42 device with ISA 16/32bit bus interface
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -114,9 +115,14 @@
 #define REG_P1CR4		0x02
 #define REG_P1SR		0x04
 
+/* flags passed by platform_device for configuration */
+#define	MICREL_KS884X		0x01	/* 0=Timeberdale(FPGA), 1=Micrel */
+#define	KS884X_16BIT		0x02	/*  1=16bit, 0=32bit */
+
 struct ks8842_adapter {
 	void __iomem	*hw_addr;
 	int		irq;
+	unsigned long	conf_flags;	/* copy of platform_device config */
 	struct tasklet_struct	tasklet;
 	spinlock_t	lock; /* spinlock to be interrupt safe */
 	struct work_struct timeout_work;
@@ -192,15 +198,21 @@ static inline u32 ks8842_read32(struct ks8842_adapter *adapter, u16 bank,
 
 static void ks8842_reset(struct ks8842_adapter *adapter)
 {
-	/* The KS8842 goes haywire when doing softare reset
-	 * a work around in the timberdale IP is implemented to
-	 * do a hardware reset instead
-	ks8842_write16(adapter, 3, 1, REG_GRR);
-	msleep(10);
-	iowrite16(0, adapter->hw_addr + REG_GRR);
-	*/
-	iowrite32(0x1, adapter->hw_addr + REG_TIMB_RST);
-	msleep(20);
+	if (adapter->conf_flags & MICREL_KS884X) {
+		ks8842_write16(adapter, 3, 1, REG_GRR);
+		msleep(10);
+		iowrite16(0, adapter->hw_addr + REG_GRR);
+	} else {
+		/* The KS8842 goes haywire when doing softare reset
+		* a work around in the timberdale IP is implemented to
+		* do a hardware reset instead
+		ks8842_write16(adapter, 3, 1, REG_GRR);
+		msleep(10);
+		iowrite16(0, adapter->hw_addr + REG_GRR);
+		*/
+		iowrite32(0x1, adapter->hw_addr + REG_TIMB_RST);
+		msleep(20);
+	}
 }
 
 static void ks8842_update_link_status(struct net_device *netdev,
@@ -269,8 +281,10 @@ static void ks8842_reset_hw(struct ks8842_adapter *adapter)
 
 	/* restart port auto-negotiation */
 	ks8842_enable_bits(adapter, 49, 1 << 13, REG_P1CR4);
-	/* only advertise 10Mbps */
-	ks8842_clear_bits(adapter, 49, 3 << 2, REG_P1CR4);
+
+	if (!(adapter->conf_flags & MICREL_KS884X))
+		/* only advertise 10Mbps */
+		ks8842_clear_bits(adapter, 49, 3 << 2, REG_P1CR4);
 
 	/* Enable the transmitter */
 	ks8842_enable_tx(adapter);
@@ -296,13 +310,28 @@ static void ks8842_read_mac_addr(struct ks8842_adapter *adapter, u8 *dest)
 	for (i = 0; i < ETH_ALEN; i++)
 		dest[ETH_ALEN - i - 1] = ks8842_read8(adapter, 2, REG_MARL + i);
 
-	/* make sure the switch port uses the same MAC as the QMU */
-	mac = ks8842_read16(adapter, 2, REG_MARL);
-	ks8842_write16(adapter, 39, mac, REG_MACAR1);
-	mac = ks8842_read16(adapter, 2, REG_MARM);
-	ks8842_write16(adapter, 39, mac, REG_MACAR2);
-	mac = ks8842_read16(adapter, 2, REG_MARH);
-	ks8842_write16(adapter, 39, mac, REG_MACAR3);
+	if (adapter->conf_flags & MICREL_KS884X) {
+		/*
+		the sequence of saving mac addr between MAC and Switch is
+		different.
+		*/
+
+		mac = ks8842_read16(adapter, 2, REG_MARL);
+		ks8842_write16(adapter, 39, mac, REG_MACAR3);
+		mac = ks8842_read16(adapter, 2, REG_MARM);
+		ks8842_write16(adapter, 39, mac, REG_MACAR2);
+		mac = ks8842_read16(adapter, 2, REG_MARH);
+		ks8842_write16(adapter, 39, mac, REG_MACAR1);
+	} else {
+
+		/* make sure the switch port uses the same MAC as the QMU */
+		mac = ks8842_read16(adapter, 2, REG_MARL);
+		ks8842_write16(adapter, 39, mac, REG_MACAR1);
+		mac = ks8842_read16(adapter, 2, REG_MARM);
+		ks8842_write16(adapter, 39, mac, REG_MACAR2);
+		mac = ks8842_read16(adapter, 2, REG_MARH);
+		ks8842_write16(adapter, 39, mac, REG_MACAR3);
+	}
 }
 
 static void ks8842_write_mac_addr(struct ks8842_adapter *adapter, u8 *mac)
@@ -313,8 +342,25 @@ static void ks8842_write_mac_addr(struct ks8842_adapter *adapter, u8 *mac)
 	spin_lock_irqsave(&adapter->lock, flags);
 	for (i = 0; i < ETH_ALEN; i++) {
 		ks8842_write8(adapter, 2, mac[ETH_ALEN - i - 1], REG_MARL + i);
-		ks8842_write8(adapter, 39, mac[ETH_ALEN - i - 1],
-			REG_MACAR1 + i);
+		if (!(adapter->conf_flags & MICREL_KS884X))
+			ks8842_write8(adapter, 39, mac[ETH_ALEN - i - 1],
+				REG_MACAR1 + i);
+	}
+
+	if (adapter->conf_flags & MICREL_KS884X) {
+		/*
+		the sequence of saving mac addr between MAC and Switch is
+		different.
+		*/
+
+		u16 mac;
+
+		mac = ks8842_read16(adapter, 2, REG_MARL);
+		ks8842_write16(adapter, 39, mac, REG_MACAR3);
+		mac = ks8842_read16(adapter, 2, REG_MARM);
+		ks8842_write16(adapter, 39, mac, REG_MACAR2);
+		mac = ks8842_read16(adapter, 2, REG_MARH);
+		ks8842_write16(adapter, 39, mac, REG_MACAR1);
 	}
 	spin_unlock_irqrestore(&adapter->lock, flags);
 }
@@ -328,8 +374,6 @@ static int ks8842_tx_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct ks8842_adapter *adapter = netdev_priv(netdev);
 	int len = skb->len;
-	u32 *ptr = (u32 *)skb->data;
-	u32 ctrl;
 
 	netdev_dbg(netdev, "%s: len %u head %p data %p tail %p end %p\n",
 		__func__, skb->len, skb->head, skb->data,
@@ -339,17 +383,34 @@ static int ks8842_tx_frame(struct sk_buff *skb, struct net_device *netdev)
 	if (ks8842_tx_fifo_space(adapter) < len + 8)
 		return NETDEV_TX_BUSY;
 
-	/* the control word, enable IRQ, port 1 and the length */
-	ctrl = 0x8000 | 0x100 | (len << 16);
-	ks8842_write32(adapter, 17, ctrl, REG_QMU_DATA_LO);
+	if (adapter->conf_flags & KS884X_16BIT) {
+		u16 *ptr16 = (u16 *)skb->data;
+		ks8842_write16(adapter, 17, 0x8000 | 0x100, REG_QMU_DATA_LO);
+		ks8842_write16(adapter, 17, (u16)len, REG_QMU_DATA_HI);
+		netdev->stats.tx_bytes += len;
+
+		/* copy buffer */
+		while (len > 0) {
+			iowrite16(*ptr16++, adapter->hw_addr + REG_QMU_DATA_LO);
+			iowrite16(*ptr16++, adapter->hw_addr + REG_QMU_DATA_HI);
+			len -= sizeof(u32);
+		}
+	} else {
+
+		u32 *ptr = (u32 *)skb->data;
+		u32 ctrl;
+		/* the control word, enable IRQ, port 1 and the length */
+		ctrl = 0x8000 | 0x100 | (len << 16);
+		ks8842_write32(adapter, 17, ctrl, REG_QMU_DATA_LO);
 
-	netdev->stats.tx_bytes += len;
+		netdev->stats.tx_bytes += len;
 
-	/* copy buffer */
-	while (len > 0) {
-		iowrite32(*ptr, adapter->hw_addr + REG_QMU_DATA_LO);
-		len -= sizeof(u32);
-		ptr++;
+		/* copy buffer */
+		while (len > 0) {
+			iowrite32(*ptr, adapter->hw_addr + REG_QMU_DATA_LO);
+			len -= sizeof(u32);
+			ptr++;
+		}
 	}
 
 	/* enqueue packet */
@@ -363,12 +424,23 @@ static int ks8842_tx_frame(struct sk_buff *skb, struct net_device *netdev)
 static void ks8842_rx_frame(struct net_device *netdev,
 	struct ks8842_adapter *adapter)
 {
-	u32 status = ks8842_read32(adapter, 17, REG_QMU_DATA_LO);
-	int len = (status >> 16) & 0x7ff;
+	u16 status16;
+	u32 status;
+	int len;
 
-	status &= 0xffff;
-
-	netdev_dbg(netdev, "%s - rx_data: status: %x\n", __func__, status);
+	if (adapter->conf_flags & KS884X_16BIT) {
+		status16 = ks8842_read16(adapter, 17, REG_QMU_DATA_LO);
+		len  = (int)ks8842_read16(adapter, 17, REG_QMU_DATA_HI);
+		len &= 0xffff;
+		netdev_dbg(netdev, "%s - rx_data: status: %x\n",
+			   __func__, status16);
+	} else {
+		status = ks8842_read32(adapter, 17, REG_QMU_DATA_LO);
+		len = (status >> 16) & 0x7ff;
+		status &= 0xffff;
+		netdev_dbg(netdev, "%s - rx_data: status: %x\n",
+			   __func__, status);
+	}
 
 	/* check the status */
 	if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) {
@@ -376,22 +448,32 @@ static void ks8842_rx_frame(struct net_device *netdev,
 
 		netdev_dbg(netdev, "%s, got package, len: %d\n", __func__, len);
 		if (skb) {
-			u32 *data;
 
 			netdev->stats.rx_packets++;
 			netdev->stats.rx_bytes += len;
 			if (status & RXSR_MULTICAST)
 				netdev->stats.multicast++;
 
-			data = (u32 *)skb_put(skb, len);
-
-			ks8842_select_bank(adapter, 17);
-			while (len > 0) {
-				*data++ = ioread32(adapter->hw_addr +
-					REG_QMU_DATA_LO);
-				len -= sizeof(u32);
+			if (adapter->conf_flags & KS884X_16BIT) {
+				u16 *data16 = (u16 *)skb_put(skb, len);
+				ks8842_select_bank(adapter, 17);
+				while (len > 0) {
+					*data16++ = ioread16(adapter->hw_addr +
+						REG_QMU_DATA_LO);
+					*data16++ = ioread16(adapter->hw_addr +
+						REG_QMU_DATA_HI);
+					len -= sizeof(u32);
+				}
+			} else {
+				u32 *data = (u32 *)skb_put(skb, len);
+
+				ks8842_select_bank(adapter, 17);
+				while (len > 0) {
+					*data++ = ioread32(adapter->hw_addr +
+						REG_QMU_DATA_LO);
+					len -= sizeof(u32);
+				}
 			}
-
 			skb->protocol = eth_type_trans(skb, netdev);
 			netif_rx(skb);
 		} else
@@ -669,6 +751,8 @@ static int __devinit ks8842_probe(struct platform_device *pdev)
 	adapter->netdev = netdev;
 	INIT_WORK(&adapter->timeout_work, ks8842_tx_timeout_work);
 	adapter->hw_addr = ioremap(iomem->start, resource_size(iomem));
+	adapter->conf_flags = iomem->flags;
+
 	if (!adapter->hw_addr)
 		goto err_ioremap;
 
-- 
1.7.1.1


^ permalink raw reply related

* [PATCH] bnx2: Enable MSI-X even if the amount of vectors is smaller than BNX2_MAX_MSIX_VEC
From: leitao @ 2010-07-13 20:42 UTC (permalink / raw)
  To: mchan; +Cc: netdev, Breno Leitão

First of all, the function bnx2_enable_msix() has the msix_vecs parameter,
but it's not used to request the amount of vectors. Currently the drivers is
always requesting BNX2_MAX_MSIX_VEC vectors, even when the msix_vecs is
different from it.

Also, if the amount of available vectors are smaller than BNX2_MAX_MSIX_VEC,
the MSI-X is disabled, which is something bad.

So, this patch tries to fix both issues. Now if the available amount of vectors
is smaller than the requested amount, the driver re-request the current available
amount and proceed with these vectors.

Signed-off-by: Breno Leitão <leitao@linux.vnet.ibm.com>
---
 drivers/net/bnx2.c |   16 +++++++++-------
 1 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 1174322..70ee664 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -860,7 +860,7 @@ bnx2_alloc_mem(struct bnx2 *bp)
 	bnapi->hw_rx_cons_ptr =
 		&bnapi->status_blk.msi->status_rx_quick_consumer_index0;
 	if (bp->flags & BNX2_FLAG_MSIX_CAP) {
-		for (i = 1; i < BNX2_MAX_MSIX_VEC; i++) {
+		for (i = 1; i < bp->irq_nvecs; i++) {
 			struct status_block_msix *sblk;
 
 			bnapi = &bp->bnx2_napi[i];
@@ -4886,7 +4886,7 @@ bnx2_init_chip(struct bnx2 *bp)
 	bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG3, BNX2_RBUF_CONFIG3_VAL(mtu));
 
 	memset(bp->bnx2_napi[0].status_blk.msi, 0, bp->status_stats_size);
-	for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
+	for (i = 0; i < bp->irq_nvecs; i++)
 		bp->bnx2_napi[i].last_status_idx = 0;
 
 	bp->idle_chk_status_idx = 0xffff;
@@ -5007,7 +5007,7 @@ bnx2_clear_ring_states(struct bnx2 *bp)
 	struct bnx2_rx_ring_info *rxr;
 	int i;
 
-	for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
+	for (i = 0; i < bp->irq_nvecs; i++) {
 		bnapi = &bp->bnx2_napi[i];
 		txr = &bnapi->tx_ring;
 		rxr = &bnapi->rx_ring;
@@ -6148,13 +6148,15 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs)
 		msix_ent[i].vector = 0;
 	}
 
-	rc = pci_enable_msix(bp->pdev, msix_ent, BNX2_MAX_MSIX_VEC);
-	if (rc != 0)
-		return;
+	do {
+		rc = pci_enable_msix(bp->pdev, msix_ent, msix_vecs);
+		if (rc > 0)
+			msix_vecs = rc;
+	} while (rc > 0);
 
 	bp->irq_nvecs = msix_vecs;
 	bp->flags |= BNX2_FLAG_USING_MSIX | BNX2_FLAG_ONE_SHOT_MSI;
-	for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
+	for (i = 0; i < msix_vecs; i++) {
 		bp->irq_tbl[i].vector = msix_ent[i].vector;
 		snprintf(bp->irq_tbl[i].name, len, "%s-%d", dev->name, i);
 		bp->irq_tbl[i].handler = bnx2_msi_1shot;
-- 
1.6.0.2


^ permalink raw reply related

* Re: [PATCH] bnx2: Enable MSI-X even if the amount of vectors is smaller than BNX2_MAX_MSIX_VEC
From: Michael Chan @ 2010-07-13 19:40 UTC (permalink / raw)
  To: leitao@linux.vnet.ibm.com; +Cc: netdev@vger.kernel.org
In-Reply-To: <1279053766-8079-1-git-send-email-leitao@linux.vnet.ibm.com>


On Tue, 2010-07-13 at 13:42 -0700, leitao@linux.vnet.ibm.com wrote:
> First of all, the function bnx2_enable_msix() has the msix_vecs parameter,
> but it's not used to request the amount of vectors. Currently the drivers is
> always requesting BNX2_MAX_MSIX_VEC vectors, even when the msix_vecs is
> different from it.

The chip was originally designed to work in MSI-X mode only if all
vectors have been configured, that's why it was coded this way.
However, there is a register (BNX2_HC_MSIX_BIT_VECTOR) that we program
to make the chip think that all vectors are configured.  We always
program 0x1ff instead of the actual number of vectors, so it should work
with any number of vectors.  I'd like to do more testing first.

We need to at least allocate one more vector for the cnic driver.  I'll
fix that and send a revised and tested patch.

Thanks.

> 
> Also, if the amount of available vectors are smaller than BNX2_MAX_MSIX_VEC,
> the MSI-X is disabled, which is something bad.
> 
> So, this patch tries to fix both issues. Now if the available amount of vectors
> is smaller than the requested amount, the driver re-request the current available
> amount and proceed with these vectors.
> 
> Signed-off-by: Breno Leitão <leitao@linux.vnet.ibm.com>
> ---
>  drivers/net/bnx2.c |   16 +++++++++-------
>  1 files changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
> index 1174322..70ee664 100644
> --- a/drivers/net/bnx2.c
> +++ b/drivers/net/bnx2.c
> @@ -860,7 +860,7 @@ bnx2_alloc_mem(struct bnx2 *bp)
>  	bnapi->hw_rx_cons_ptr =
>  		&bnapi->status_blk.msi->status_rx_quick_consumer_index0;
>  	if (bp->flags & BNX2_FLAG_MSIX_CAP) {
> -		for (i = 1; i < BNX2_MAX_MSIX_VEC; i++) {
> +		for (i = 1; i < bp->irq_nvecs; i++) {
>  			struct status_block_msix *sblk;
>  
>  			bnapi = &bp->bnx2_napi[i];
> @@ -4886,7 +4886,7 @@ bnx2_init_chip(struct bnx2 *bp)
>  	bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG3, BNX2_RBUF_CONFIG3_VAL(mtu));
>  
>  	memset(bp->bnx2_napi[0].status_blk.msi, 0, bp->status_stats_size);
> -	for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
> +	for (i = 0; i < bp->irq_nvecs; i++)
>  		bp->bnx2_napi[i].last_status_idx = 0;
>  
>  	bp->idle_chk_status_idx = 0xffff;
> @@ -5007,7 +5007,7 @@ bnx2_clear_ring_states(struct bnx2 *bp)
>  	struct bnx2_rx_ring_info *rxr;
>  	int i;
>  
> -	for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
> +	for (i = 0; i < bp->irq_nvecs; i++) {
>  		bnapi = &bp->bnx2_napi[i];
>  		txr = &bnapi->tx_ring;
>  		rxr = &bnapi->rx_ring;
> @@ -6148,13 +6148,15 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs)
>  		msix_ent[i].vector = 0;
>  	}
>  
> -	rc = pci_enable_msix(bp->pdev, msix_ent, BNX2_MAX_MSIX_VEC);
> -	if (rc != 0)
> -		return;
> +	do {
> +		rc = pci_enable_msix(bp->pdev, msix_ent, msix_vecs);
> +		if (rc > 0)
> +			msix_vecs = rc;
> +	} while (rc > 0);
>  
>  	bp->irq_nvecs = msix_vecs;
>  	bp->flags |= BNX2_FLAG_USING_MSIX | BNX2_FLAG_ONE_SHOT_MSI;
> -	for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
> +	for (i = 0; i < msix_vecs; i++) {
>  		bp->irq_tbl[i].vector = msix_ent[i].vector;
>  		snprintf(bp->irq_tbl[i].name, len, "%s-%d", dev->name, i);
>  		bp->irq_tbl[i].handler = bnx2_msi_1shot;



^ permalink raw reply

* Re: [PATCH] eth16i: fix memory leak
From: Kulikov Vasiliy @ 2010-07-13 19:48 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: kernel-janitors, Mika Kuoppala, David S. Miller,
	Stephen Hemminger, Eric Dumazet, Tejun Heo, Jiri Pirko, netdev
In-Reply-To: <20100713114347.GK5658@bicker>

On Tue, Jul 13, 2010 at 13:43 +0200, Dan Carpenter wrote:
> On Tue, Jul 13, 2010 at 03:22:18PM +0400, Kulikov Vasiliy wrote:
> > Free allocated netdev if no probe is expected.
> > 
> > Signed-off-by: Kulikov Vasiliy <segooon@gmail.com>
> > ---
> >  drivers/net/eth16i.c |    4 +++-
> >  1 files changed, 3 insertions(+), 1 deletions(-)
> > 
> > diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c
> > index 874973f..2bdd394 100644
> > --- a/drivers/net/eth16i.c
> > +++ b/drivers/net/eth16i.c
> > @@ -1442,8 +1442,10 @@ int __init init_module(void)
> >  		dev->if_port = eth16i_parse_mediatype(mediatype[this_dev]);
> >  
> >  		if(io[this_dev] == 0) {
> > -			if(this_dev != 0) /* Only autoprobe 1st one */
> > +			if (this_dev != 0) { /* Only autoprobe 1st one */
> > +				free_netdev(def);
> 					    ^^^
> 				free_netdev(dev);
Heh, this function is surrounded with #ifdef MODULE #endif, so this typo
was not detected at my test nonmoduled compilation. Thanks.

Patch v2 is comming.

> 
> regards,
> dan carpenter
> 
> >  				break;
> > +			}
> >  
> >  			printk(KERN_NOTICE "eth16i.c: Presently autoprobing (not recommended) for a single card.\n");
> >  		}
> > -- 
> 

^ permalink raw reply

* [PATCH v2] eth16i: fix memory leak
From: Kulikov Vasiliy @ 2010-07-13 19:49 UTC (permalink / raw)
  To: kernel-janitors
  Cc: Mika Kuoppala, David S. Miller, Stephen Hemminger, Eric Dumazet,
	Tejun Heo, Jiri Pirko, netdev
In-Reply-To: <20100713114347.GK5658@bicker>

Free allocated netdev if no probe is expected.

Signed-off-by: Kulikov Vasiliy <segooon@gmail.com>
---
 drivers/net/eth16i.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c
index 874973f..10e39f2 100644
--- a/drivers/net/eth16i.c
+++ b/drivers/net/eth16i.c
@@ -1442,8 +1442,10 @@ int __init init_module(void)
 		dev->if_port = eth16i_parse_mediatype(mediatype[this_dev]);
 
 		if(io[this_dev] == 0) {
-			if(this_dev != 0) /* Only autoprobe 1st one */
+			if (this_dev != 0) { /* Only autoprobe 1st one */
+				free_netdev(dev);
 				break;
+			}
 
 			printk(KERN_NOTICE "eth16i.c: Presently autoprobing (not recommended) for a single card.\n");
 		}
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH -mmotm 05/30] mm: sl[au]b: add knowledge of reserve pages
From: Pekka Enberg @ 2010-07-13 20:33 UTC (permalink / raw)
  To: Xiaotian Feng
  Cc: linux-mm-Bw31MaZKKs3YtjvyW6yDsg, linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA, riel-H+wXaHxf7aLQT0dZR+AlfA,
	cl-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	a.p.zijlstra-/NLkJaSkS4VmR6Xm/wNWPw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, lwang-H+wXaHxf7aLQT0dZR+AlfA,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <20100713101747.2835.45722.sendpatchset-bd3XojVv5Xrm7B5McmCzzQ@public.gmane.org>

Hi Xiaotian!

I would actually prefer that the SLAB, SLOB, and SLUB changes were in
separate patches to make reviewing easier.

Looking at SLUB:

On Tue, Jul 13, 2010 at 1:17 PM, Xiaotian Feng <dfeng-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> diff --git a/mm/slub.c b/mm/slub.c
> index 7bb7940..7a5d6dc 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -27,6 +27,8 @@
>  #include <linux/memory.h>
>  #include <linux/math64.h>
>  #include <linux/fault-inject.h>
> +#include "internal.h"
> +
>
>  /*
>  * Lock order:
> @@ -1139,7 +1141,8 @@ static void setup_object(struct kmem_cache *s, struct page *page,
>                s->ctor(object);
>  }
>
> -static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
> +static
> +struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node, int *reserve)
>  {
>        struct page *page;
>        void *start;
> @@ -1153,6 +1156,8 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
>        if (!page)
>                goto out;
>
> +       *reserve = page->reserve;
> +
>        inc_slabs_node(s, page_to_nid(page), page->objects);
>        page->slab = s;
>        page->flags |= 1 << PG_slab;
> @@ -1606,10 +1611,20 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
>  {
>        void **object;
>        struct page *new;
> +       int reserve;
>
>        /* We handle __GFP_ZERO in the caller */
>        gfpflags &= ~__GFP_ZERO;
>
> +       if (unlikely(c->reserve)) {
> +               /*
> +                * If the current slab is a reserve slab and the current
> +                * allocation context does not allow access to the reserves we
> +                * must force an allocation to test the current levels.
> +                */
> +               if (!(gfp_to_alloc_flags(gfpflags) & ALLOC_NO_WATERMARKS))
> +                       goto grow_slab;

OK, so assume that:

  (1) c->reserve is set to one

  (2) GFP flags don't allow dipping into the reserves

  (3) we've managed to free enough pages so normal
       allocations are fine

  (4) the page from reserves is not yet empty

we will call flush_slab() and put the "emergency page" on partial list
and clear c->reserve. This effectively means that now some other
allocation can fetch the partial page and start to use it. Is this OK?
Who makes sure the emergency reserves are large enough for the next
out-of-memory condition where we swap over NFS?

> +       }
>        if (!c->page)
>                goto new_slab;
>
> @@ -1623,8 +1638,8 @@ load_freelist:
>        object = c->page->freelist;
>        if (unlikely(!object))
>                goto another_slab;
> -       if (unlikely(SLABDEBUG && PageSlubDebug(c->page)))
> -               goto debug;
> +       if (unlikely(SLABDEBUG && PageSlubDebug(c->page) || c->reserve))
> +               goto slow_path;
>
>        c->freelist = get_freepointer(s, object);
>        c->page->inuse = c->page->objects;
> @@ -1646,16 +1661,18 @@ new_slab:
>                goto load_freelist;
>        }
>
> +grow_slab:
>        if (gfpflags & __GFP_WAIT)
>                local_irq_enable();
>
> -       new = new_slab(s, gfpflags, node);
> +       new = new_slab(s, gfpflags, node, &reserve);
>
>        if (gfpflags & __GFP_WAIT)
>                local_irq_disable();
>
>        if (new) {
>                c = __this_cpu_ptr(s->cpu_slab);
> +               c->reserve = reserve;
>                stat(s, ALLOC_SLAB);
>                if (c->page)
>                        flush_slab(s, c);
> @@ -1667,10 +1684,20 @@ new_slab:
>        if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit())
>                slab_out_of_memory(s, gfpflags, node);
>        return NULL;
> -debug:
> -       if (!alloc_debug_processing(s, c->page, object, addr))
> +
> +slow_path:
> +       if (!c->reserve && !alloc_debug_processing(s, c->page, object, addr))
>                goto another_slab;
>
> +       /*
> +        * Avoid the slub fast path in slab_alloc() by not setting
> +        * c->freelist and the fast path in slab_free() by making
> +        * node_match() fail by setting c->node to -1.
> +        *
> +        * We use this for for debug and reserve checks which need
> +        * to be done for each allocation.
> +        */
> +
>        c->page->inuse++;
>        c->page->freelist = get_freepointer(s, object);
>        c->node = -1;
> @@ -2095,10 +2122,11 @@ static void early_kmem_cache_node_alloc(gfp_t gfpflags, int node)
>        struct page *page;
>        struct kmem_cache_node *n;
>        unsigned long flags;
> +       int reserve;
>
>        BUG_ON(kmalloc_caches->size < sizeof(struct kmem_cache_node));
>
> -       page = new_slab(kmalloc_caches, gfpflags, node);
> +       page = new_slab(kmalloc_caches, gfpflags, node, &reserve);
>
>        BUG_ON(!page);
>        if (page_to_nid(page) != node) {
> --
> 1.7.1.1
>
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo-Bw31MaZKKs0EbZ0PF+XxCw@public.gmane.org  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org"> email-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org </a>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply


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