Netdev List
 help / color / mirror / Atom feed
* [PATCH] can: mcp251x: avoid repeated frame bug
From: Marc Kleine-Budde @ 2012-09-04 20:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-can, Benoît Locher, stable, Marc Kleine-Budde
In-Reply-To: <1346792142-17609-1-git-send-email-mkl@pengutronix.de>

From: Benoît Locher <Benoit.Locher@skf.com>

The MCP2515 has a silicon bug causing repeated frame transmission, see section
5 of MCP2515 Rev. B Silicon Errata Revision G (March 2007).

Basically, setting TXBnCTRL.TXREQ in either SPI mode (00 or 11) will eventually
cause the bug. The workaround proposed by Microchip is to use mode 00 and send
a RTS command on the SPI bus to initiate the transmission.

Cc: <stable@vger.kernel.org>
Signed-off-by: Benoît Locher <Benoit.Locher@skf.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/mcp251x.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c
index a580db2..26e7129 100644
--- a/drivers/net/can/mcp251x.c
+++ b/drivers/net/can/mcp251x.c
@@ -83,6 +83,11 @@
 #define INSTRUCTION_LOAD_TXB(n)	(0x40 + 2 * (n))
 #define INSTRUCTION_READ_RXB(n)	(((n) == 0) ? 0x90 : 0x94)
 #define INSTRUCTION_RESET	0xC0
+#define RTS_TXB0		0x01
+#define RTS_TXB1		0x02
+#define RTS_TXB2		0x04
+#define INSTRUCTION_RTS(n)	(0x80 | ((n) & 0x07))
+
 
 /* MPC251x registers */
 #define CANSTAT	      0x0e
@@ -397,6 +402,7 @@ static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf,
 static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,
 			  int tx_buf_idx)
 {
+	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
 	u32 sid, eid, exide, rtr;
 	u8 buf[SPI_TRANSFER_BUF_LEN];
 
@@ -418,7 +424,10 @@ static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,
 	buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc;
 	memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc);
 	mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx);
-	mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx), TXBCTRL_TXREQ);
+
+	/* use INSTRUCTION_RTS, to avoid "repeated frame problem" */
+	priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx);
+	mcp251x_spi_trans(priv->spi, 1);
 }
 
 static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf,
-- 
1.7.10


^ permalink raw reply related

* Re: [Bug 47021] New: kernel panic with l2tpv3 & mtu > 1500
From: Eric Dumazet @ 2012-09-04 20:57 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, a1bert
In-Reply-To: <20120904125458.7d97ec38@nehalam.linuxnetplumber.net>

On Tue, 2012-09-04 at 12:54 -0700, Stephen Hemminger wrote:

> 
> I guess nobody ever looked inside this code. That seems like an obvious bug.

It seems that l2tp lacks ECN support as well.

^ permalink raw reply

* Re: [PATCH v2 1/2] tcp: add generic netlink support for tcp_metrics
From: Julian Anastasov @ 2012-09-04 21:00 UTC (permalink / raw)
  To: David Miller; +Cc: eric.dumazet, netdev, shemminger, paulmck
In-Reply-To: <20120904.154708.2099268692603008096.davem@davemloft.net>


	Hello,

On Tue, 4 Sep 2012, David Miller wrote:

> From: Julian Anastasov <ja@ssi.bg>
> Date: Mon, 3 Sep 2012 11:22:15 +0300 (EEST)
> 
> > 	BTW, is it appropriate to use kmem_cache for
> > metrics and as result call_rcu for freeing?
> 
> I think it would work as things are implemented currently in
> slab/slub/slob, however I would not rely upon it.
> 
> If you do move to a SLAB cache for the tcp metrics objects,
> you might consider SLAB_DESTROY_BY_RCU.  It's a very delicate
> facility (read the huge comment in linux/slab.h) but I think
> it provides the semantics we need for TCP metrics blobs.

	ok, I'll not mix it with the genl support
because I'm not prepared to do it soon...

> Looking forward to v3 :-)

	Sending...

Regards

--
Julian Anastasov <ja@ssi.bg>

^ permalink raw reply

* Re: [PATCH v3 01/17] hashtable: introduce a small and naive hashtable
From: Steven Rostedt @ 2012-09-04 20:59 UTC (permalink / raw)
  To: Pedro Alves
  Cc: snitzer-H+wXaHxf7aLQT0dZR+AlfA, neilb-l3A5Bk7waGM,
	fweisbec-Re5JQEeQqe8AvxtiuMwx3w,
	Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA,
	bfields-uC3wQj2KruNg9hUCZPvPmw,
	paul.gortmaker-CWA4WttNNZF54TAoqtyWWQ,
	dm-devel-H+wXaHxf7aLQT0dZR+AlfA, agk-H+wXaHxf7aLQT0dZR+AlfA,
	aarcange-H+wXaHxf7aLQT0dZR+AlfA, rds-devel-N0ozoZBvEnrZJqsBc5GL+g,
	eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
	venkat.x.venkatsubra-QHcLZuEGTsvQT0dZR+AlfA,
	ccaulfie-H+wXaHxf7aLQT0dZR+AlfA, mingo-X9Un+BFzKDI,
	dev-yBygre7rU0TnMu66kgdUjQ, ericvh-Re5JQEeQqe8AvxtiuMwx3w,
	josh-iaAMLnmF4UmaiuxdJuQwMA, lw-BthXqXjhjHXQFUHtdCDX3A,
	Mathieu Desnoyers, Sasha Levin, axboe-tSWWG44O7X1aa/9Udqfwiw,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA, edumazet-hpIqsD4AKlfQT0dZR+AlfA,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, ejt-H+wXaHxf7aLQT0dZR+AlfA,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, Tejun Heo,
	teigland-H+wXaHxf7aLQT0dZR+AlfA,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <50463883.8080706-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

On Tue, 2012-09-04 at 18:21 +0100, Pedro Alves wrote:
> On 09/04/2012 06:17 PM, Steven Rostedt wrote:
> > On Tue, 2012-09-04 at 17:40 +0100, Pedro Alves wrote:
> > 
> >> BTW, you can also go a step further and remove the need to close with double }},
> >> with something like:
> >>
> >> #define do_for_each_ftrace_rec(pg, rec)                                          \
> >>         for (pg = ftrace_pages_start, rec = &pg->records[pg->index];             \
> >>              pg && rec == &pg->records[pg->index];                               \
> >>              pg = pg->next)                                                      \
> >>           for (rec = pg->records; rec < &pg->records[pg->index]; rec++)
> >>
> > 
> > Yeah, but why bother? It's hidden in a macro, and the extra '{ }' shows
> > that this is something "special".
> 
> The point of both changes is that there's nothing special in the end
> at all.  It all just works...
> 

It would still fail on a 'break'. The 'while' macro tells us that it is
special, because in the end, it wont work.

-- Steve

^ permalink raw reply

* [PATCH v3 0/3] Interface for TCP Metrics
From: Julian Anastasov @ 2012-09-04 21:03 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Stephen Hemminger

	This patchset contains 3 patches, one for kernel
and two for iproute2. We add DUMP/GET/DEL support for
genl "tcp_metrics" and minimal support for filtering
by address prefix and family in user space.

	I tested show/del/flush, filtering by family, IPv4 prefix,
output for metrics such as rtt, rttvar, cwnd, ssthresh (after
modifying route). I didn't tested output for fast open.

	May be some corrections in output can be desired.

v2:
- patch 1: remove rcu_assign_pointer, add tcp_metrics_flush_all
- patch 2: properly flush by specifying address, improve man page

v3:
- patch 1: remove synchronize_rcu
- patch 2: create libgenl.h and libgenl.c
- new patch 3: use libgenl.c also in ipl2tp.c

^ permalink raw reply

* [PATCH v3 1/3] tcp: add generic netlink support for tcp_metrics
From: Julian Anastasov @ 2012-09-04 21:03 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Stephen Hemminger
In-Reply-To: <1346792597-2427-1-git-send-email-ja@ssi.bg>

	Add support for genl "tcp_metrics". No locking
is changed, only that now we can unlink and delete
entries after grace period. We implement get/del for
single entry and dump to support show/flush filtering
in user space. Del without address attribute causes
flush for all addresses, sadly under genl_mutex.

v2:
- remove rcu_assign_pointer as suggested by Eric Dumazet,
it is not needed because there are no other writes under lock
- move the flushing code in tcp_metrics_flush_all

v3:
- remove synchronize_rcu on flush as suggested by Eric Dumazet

Signed-off-by: Julian Anastasov <ja@ssi.bg>
---
 include/linux/Kbuild        |    1 +
 include/linux/tcp_metrics.h |   54 +++++++
 net/ipv4/tcp_metrics.c      |  354 +++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 396 insertions(+), 13 deletions(-)
 create mode 100644 include/linux/tcp_metrics.h

diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 1f2c1c7..90da0af 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -363,6 +363,7 @@ header-y += sysctl.h
 header-y += sysinfo.h
 header-y += taskstats.h
 header-y += tcp.h
+header-y += tcp_metrics.h
 header-y += telephony.h
 header-y += termios.h
 header-y += time.h
diff --git a/include/linux/tcp_metrics.h b/include/linux/tcp_metrics.h
new file mode 100644
index 0000000..cb5157b
--- /dev/null
+++ b/include/linux/tcp_metrics.h
@@ -0,0 +1,54 @@
+/* tcp_metrics.h - TCP Metrics Interface */
+
+#ifndef _LINUX_TCP_METRICS_H
+#define _LINUX_TCP_METRICS_H
+
+#include <linux/types.h>
+
+/* NETLINK_GENERIC related info
+ */
+#define TCP_METRICS_GENL_NAME		"tcp_metrics"
+#define TCP_METRICS_GENL_VERSION	0x1
+
+enum tcp_metric_index {
+	TCP_METRIC_RTT,
+	TCP_METRIC_RTTVAR,
+	TCP_METRIC_SSTHRESH,
+	TCP_METRIC_CWND,
+	TCP_METRIC_REORDERING,
+
+	/* Always last.  */
+	__TCP_METRIC_MAX,
+};
+
+#define TCP_METRIC_MAX	(__TCP_METRIC_MAX - 1)
+
+enum {
+	TCP_METRICS_ATTR_UNSPEC,
+	TCP_METRICS_ATTR_ADDR_IPV4,		/* u32 */
+	TCP_METRICS_ATTR_ADDR_IPV6,		/* binary */
+	TCP_METRICS_ATTR_AGE,			/* msecs */
+	TCP_METRICS_ATTR_TW_TSVAL,		/* u32, raw, rcv tsval */
+	TCP_METRICS_ATTR_TW_TS_STAMP,		/* s32, sec age */
+	TCP_METRICS_ATTR_VALS,			/* nested +1, u32 */
+	TCP_METRICS_ATTR_FOPEN_MSS,		/* u16 */
+	TCP_METRICS_ATTR_FOPEN_SYN_DROPS,	/* u16, count of drops */
+	TCP_METRICS_ATTR_FOPEN_SYN_DROP_TS,	/* msecs age */
+	TCP_METRICS_ATTR_FOPEN_COOKIE,		/* binary */
+
+	__TCP_METRICS_ATTR_MAX,
+};
+
+#define TCP_METRICS_ATTR_MAX	(__TCP_METRICS_ATTR_MAX - 1)
+
+enum {
+	TCP_METRICS_CMD_UNSPEC,
+	TCP_METRICS_CMD_GET,
+	TCP_METRICS_CMD_DEL,
+
+	__TCP_METRICS_CMD_MAX,
+};
+
+#define TCP_METRICS_CMD_MAX	(__TCP_METRICS_CMD_MAX - 1)
+
+#endif /* _LINUX_TCP_METRICS_H */
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index 0abe67b..988edb6 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -8,6 +8,7 @@
 #include <linux/init.h>
 #include <linux/tcp.h>
 #include <linux/hash.h>
+#include <linux/tcp_metrics.h>
 
 #include <net/inet_connection_sock.h>
 #include <net/net_namespace.h>
@@ -17,20 +18,10 @@
 #include <net/ipv6.h>
 #include <net/dst.h>
 #include <net/tcp.h>
+#include <net/genetlink.h>
 
 int sysctl_tcp_nometrics_save __read_mostly;
 
-enum tcp_metric_index {
-	TCP_METRIC_RTT,
-	TCP_METRIC_RTTVAR,
-	TCP_METRIC_SSTHRESH,
-	TCP_METRIC_CWND,
-	TCP_METRIC_REORDERING,
-
-	/* Always last.  */
-	TCP_METRIC_MAX,
-};
-
 struct tcp_fastopen_metrics {
 	u16	mss;
 	u16	syn_loss:10;		/* Recurring Fast Open SYN losses */
@@ -45,8 +36,10 @@ struct tcp_metrics_block {
 	u32				tcpm_ts;
 	u32				tcpm_ts_stamp;
 	u32				tcpm_lock;
-	u32				tcpm_vals[TCP_METRIC_MAX];
+	u32				tcpm_vals[TCP_METRIC_MAX + 1];
 	struct tcp_fastopen_metrics	tcpm_fastopen;
+
+	struct rcu_head			rcu_head;
 };
 
 static bool tcp_metric_locked(struct tcp_metrics_block *tm,
@@ -690,6 +683,325 @@ void tcp_fastopen_cache_set(struct sock *sk, u16 mss,
 	rcu_read_unlock();
 }
 
+static struct genl_family tcp_metrics_nl_family = {
+	.id		= GENL_ID_GENERATE,
+	.hdrsize	= 0,
+	.name		= TCP_METRICS_GENL_NAME,
+	.version	= TCP_METRICS_GENL_VERSION,
+	.maxattr	= TCP_METRICS_ATTR_MAX,
+	.netnsok	= true,
+};
+
+static struct nla_policy tcp_metrics_nl_policy[TCP_METRICS_ATTR_MAX + 1] = {
+	[TCP_METRICS_ATTR_ADDR_IPV4]	= { .type = NLA_U32, },
+	[TCP_METRICS_ATTR_ADDR_IPV6]	= { .type = NLA_BINARY,
+					    .len = sizeof(struct in6_addr), },
+	/* Following attributes are not received for GET/DEL,
+	 * we keep them for reference
+	 */
+#if 0
+	[TCP_METRICS_ATTR_AGE]		= { .type = NLA_MSECS, },
+	[TCP_METRICS_ATTR_TW_TSVAL]	= { .type = NLA_U32, },
+	[TCP_METRICS_ATTR_TW_TS_STAMP]	= { .type = NLA_S32, },
+	[TCP_METRICS_ATTR_VALS]		= { .type = NLA_NESTED, },
+	[TCP_METRICS_ATTR_FOPEN_MSS]	= { .type = NLA_U16, },
+	[TCP_METRICS_ATTR_FOPEN_SYN_DROPS]	= { .type = NLA_U16, },
+	[TCP_METRICS_ATTR_FOPEN_SYN_DROP_TS]	= { .type = NLA_MSECS, },
+	[TCP_METRICS_ATTR_FOPEN_COOKIE]	= { .type = NLA_BINARY,
+					    .len = TCP_FASTOPEN_COOKIE_MAX, },
+#endif
+};
+
+/* Add attributes, caller cancels its header on failure */
+static int tcp_metrics_fill_info(struct sk_buff *msg,
+				 struct tcp_metrics_block *tm)
+{
+	struct nlattr *nest;
+	int i;
+
+	switch (tm->tcpm_addr.family) {
+	case AF_INET:
+		if (nla_put_be32(msg, TCP_METRICS_ATTR_ADDR_IPV4,
+				tm->tcpm_addr.addr.a4) < 0)
+			goto nla_put_failure;
+		break;
+	case AF_INET6:
+		if (nla_put(msg, TCP_METRICS_ATTR_ADDR_IPV6, 16,
+			    tm->tcpm_addr.addr.a6) < 0)
+			goto nla_put_failure;
+		break;
+	default:
+		return -EAFNOSUPPORT;
+	}
+
+	if (nla_put_msecs(msg, TCP_METRICS_ATTR_AGE,
+			  jiffies - tm->tcpm_stamp) < 0)
+		goto nla_put_failure;
+	if (tm->tcpm_ts_stamp) {
+		if (nla_put_s32(msg, TCP_METRICS_ATTR_TW_TS_STAMP,
+				(s32) (get_seconds() - tm->tcpm_ts_stamp)) < 0)
+			goto nla_put_failure;
+		if (nla_put_u32(msg, TCP_METRICS_ATTR_TW_TSVAL,
+				tm->tcpm_ts) < 0)
+			goto nla_put_failure;
+	}
+
+	{
+		int n = 0;
+
+		nest = nla_nest_start(msg, TCP_METRICS_ATTR_VALS);
+		if (!nest)
+			goto nla_put_failure;
+		for (i = 0; i < TCP_METRIC_MAX + 1; i++) {
+			if (!tm->tcpm_vals[i])
+				continue;
+			if (nla_put_u32(msg, i + 1, tm->tcpm_vals[i]) < 0)
+				goto nla_put_failure;
+			n++;
+		}
+		if (n)
+			nla_nest_end(msg, nest);
+		else
+			nla_nest_cancel(msg, nest);
+	}
+
+	{
+		struct tcp_fastopen_metrics tfom_copy[1], *tfom;
+		unsigned int seq;
+
+		do {
+			seq = read_seqbegin(&fastopen_seqlock);
+			tfom_copy[0] = tm->tcpm_fastopen;
+		} while (read_seqretry(&fastopen_seqlock, seq));
+
+		tfom = tfom_copy;
+		if (tfom->mss &&
+		    nla_put_u16(msg, TCP_METRICS_ATTR_FOPEN_MSS,
+				tfom->mss) < 0)
+			goto nla_put_failure;
+		if (tfom->syn_loss &&
+		    (nla_put_u16(msg, TCP_METRICS_ATTR_FOPEN_SYN_DROPS,
+				tfom->syn_loss) < 0 ||
+		     nla_put_msecs(msg, TCP_METRICS_ATTR_FOPEN_SYN_DROP_TS,
+				jiffies - tfom->last_syn_loss) < 0))
+			goto nla_put_failure;
+		if (tfom->cookie.len > 0 &&
+		    nla_put(msg, TCP_METRICS_ATTR_FOPEN_COOKIE,
+			    tfom->cookie.len, tfom->cookie.val) < 0)
+			goto nla_put_failure;
+	}
+
+	return 0;
+
+nla_put_failure:
+	return -EMSGSIZE;
+}
+
+static int tcp_metrics_dump_info(struct sk_buff *skb,
+				 struct netlink_callback *cb,
+				 struct tcp_metrics_block *tm)
+{
+	void *hdr;
+
+	hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
+			  &tcp_metrics_nl_family, NLM_F_MULTI,
+			  TCP_METRICS_CMD_GET);
+	if (!hdr)
+		return -EMSGSIZE;
+
+	if (tcp_metrics_fill_info(skb, tm) < 0)
+		goto nla_put_failure;
+
+	return genlmsg_end(skb, hdr);
+
+nla_put_failure:
+	genlmsg_cancel(skb, hdr);
+	return -EMSGSIZE;
+}
+
+static int tcp_metrics_nl_dump(struct sk_buff *skb,
+			       struct netlink_callback *cb)
+{
+	struct net *net = sock_net(skb->sk);
+	unsigned int max_rows = 1U << net->ipv4.tcp_metrics_hash_log;
+	unsigned int row, s_row = cb->args[0];
+	int s_col = cb->args[1], col = s_col;
+
+	for (row = s_row; row < max_rows; row++, s_col = 0) {
+		struct tcp_metrics_block *tm;
+		struct tcpm_hash_bucket *hb = net->ipv4.tcp_metrics_hash + row;
+
+		rcu_read_lock();
+		for (col = 0, tm = rcu_dereference(hb->chain); tm;
+		     tm = rcu_dereference(tm->tcpm_next), col++) {
+			if (col < s_col)
+				continue;
+			if (tcp_metrics_dump_info(skb, cb, tm) < 0) {
+				rcu_read_unlock();
+				goto done;
+			}
+		}
+		rcu_read_unlock();
+	}
+
+done:
+	cb->args[0] = row;
+	cb->args[1] = col;
+	return skb->len;
+}
+
+static int parse_nl_addr(struct genl_info *info, struct inetpeer_addr *addr,
+			 unsigned int *hash, int optional)
+{
+	struct nlattr *a;
+
+	a = info->attrs[TCP_METRICS_ATTR_ADDR_IPV4];
+	if (a) {
+		addr->family = AF_INET;
+		addr->addr.a4 = nla_get_be32(a);
+		*hash = (__force unsigned int) addr->addr.a4;
+		return 0;
+	}
+	a = info->attrs[TCP_METRICS_ATTR_ADDR_IPV6];
+	if (a) {
+		if (nla_len(a) != sizeof(sizeof(struct in6_addr)))
+			return -EINVAL;
+		addr->family = AF_INET6;
+		memcpy(addr->addr.a6, nla_data(a), sizeof(addr->addr.a6));
+		*hash = ipv6_addr_hash((struct in6_addr *) addr->addr.a6);
+		return 0;
+	}
+	return optional ? 1 : -EAFNOSUPPORT;
+}
+
+static int tcp_metrics_nl_cmd_get(struct sk_buff *skb, struct genl_info *info)
+{
+	struct tcp_metrics_block *tm;
+	struct inetpeer_addr addr;
+	unsigned int hash;
+	struct sk_buff *msg;
+	struct net *net = genl_info_net(info);
+	void *reply;
+	int ret;
+
+	ret = parse_nl_addr(info, &addr, &hash, 0);
+	if (ret < 0)
+		return ret;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	reply = genlmsg_put_reply(msg, info, &tcp_metrics_nl_family, 0,
+				  info->genlhdr->cmd);
+	if (!reply)
+		goto nla_put_failure;
+
+	hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log);
+	ret = -ESRCH;
+	rcu_read_lock();
+	for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm;
+	     tm = rcu_dereference(tm->tcpm_next)) {
+		if (addr_same(&tm->tcpm_addr, &addr)) {
+			ret = tcp_metrics_fill_info(msg, tm);
+			break;
+		}
+	}
+	rcu_read_unlock();
+	if (ret < 0)
+		goto out_free;
+
+	genlmsg_end(msg, reply);
+	return genlmsg_reply(msg, info);
+
+nla_put_failure:
+	ret = -EMSGSIZE;
+
+out_free:
+	nlmsg_free(msg);
+	return ret;
+}
+
+#define deref_locked_genl(p)	\
+	rcu_dereference_protected(p, lockdep_genl_is_held() && \
+				     lockdep_is_held(&tcp_metrics_lock))
+
+#define deref_genl(p)	rcu_dereference_protected(p, lockdep_genl_is_held())
+
+static int tcp_metrics_flush_all(struct net *net)
+{
+	unsigned int max_rows = 1U << net->ipv4.tcp_metrics_hash_log;
+	struct tcpm_hash_bucket *hb = net->ipv4.tcp_metrics_hash;
+	struct tcp_metrics_block *tm;
+	unsigned int row;
+
+	for (row = 0; row < max_rows; row++, hb++) {
+		spin_lock_bh(&tcp_metrics_lock);
+		tm = deref_locked_genl(hb->chain);
+		if (tm)
+			hb->chain = NULL;
+		spin_unlock_bh(&tcp_metrics_lock);
+		while (tm) {
+			struct tcp_metrics_block *next;
+
+			next = deref_genl(tm->tcpm_next);
+			kfree_rcu(tm, rcu_head);
+			tm = next;
+		}
+	}
+	return 0;
+}
+
+static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info)
+{
+	struct tcpm_hash_bucket *hb;
+	struct tcp_metrics_block *tm;
+	struct tcp_metrics_block __rcu **pp;
+	struct inetpeer_addr addr;
+	unsigned int hash;
+	struct net *net = genl_info_net(info);
+	int ret;
+
+	ret = parse_nl_addr(info, &addr, &hash, 1);
+	if (ret < 0)
+		return ret;
+	if (ret > 0)
+		return tcp_metrics_flush_all(net);
+
+	hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log);
+	hb = net->ipv4.tcp_metrics_hash + hash;
+	pp = &hb->chain;
+	spin_lock_bh(&tcp_metrics_lock);
+	for (tm = deref_locked_genl(*pp); tm;
+	     pp = &tm->tcpm_next, tm = deref_locked_genl(*pp)) {
+		if (addr_same(&tm->tcpm_addr, &addr)) {
+			*pp = tm->tcpm_next;
+			break;
+		}
+	}
+	spin_unlock_bh(&tcp_metrics_lock);
+	if (!tm)
+		return -ESRCH;
+	kfree_rcu(tm, rcu_head);
+	return 0;
+}
+
+static struct genl_ops tcp_metrics_nl_ops[] = {
+	{
+		.cmd = TCP_METRICS_CMD_GET,
+		.doit = tcp_metrics_nl_cmd_get,
+		.dumpit = tcp_metrics_nl_dump,
+		.policy = tcp_metrics_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = TCP_METRICS_CMD_DEL,
+		.doit = tcp_metrics_nl_cmd_del,
+		.policy = tcp_metrics_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+};
+
 static unsigned int tcpmhash_entries;
 static int __init set_tcpmhash_entries(char *str)
 {
@@ -753,5 +1065,21 @@ static __net_initdata struct pernet_operations tcp_net_metrics_ops = {
 
 void __init tcp_metrics_init(void)
 {
-	register_pernet_subsys(&tcp_net_metrics_ops);
+	int ret;
+
+	ret = register_pernet_subsys(&tcp_net_metrics_ops);
+	if (ret < 0)
+		goto cleanup;
+	ret = genl_register_family_with_ops(&tcp_metrics_nl_family,
+					    tcp_metrics_nl_ops,
+					    ARRAY_SIZE(tcp_metrics_nl_ops));
+	if (ret < 0)
+		goto cleanup_subsys;
+	return;
+
+cleanup_subsys:
+	unregister_pernet_subsys(&tcp_net_metrics_ops);
+
+cleanup:
+	return;
 }
-- 
1.7.3.4

^ permalink raw reply related

* [PATCH v3 2/3] iproute2: add support for tcp_metrics
From: Julian Anastasov @ 2012-09-04 21:03 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Stephen Hemminger
In-Reply-To: <1346792597-2427-1-git-send-email-ja@ssi.bg>

	ip tcp_metrics/tcpmetrics

v2:
- On flush we should provide the address in req2
- "flush all" should use single del, just like when "all" is not provided
- Explain printed information in man page

v3:
- move genl code into new files: libgenl.h and libgenl.c

Signed-off-by: Julian Anastasov <ja@ssi.bg>
---

diff -urpN iproute2-3.5.1/include/libgenl.h iproute2-3.5.1-tcp_metrics/include/libgenl.h
--- iproute2-3.5.1/include/libgenl.h	1970-01-01 02:00:00.000000000 +0200
+++ iproute2-3.5.1-tcp_metrics/include/libgenl.h	2012-09-04 01:10:25.606915458 +0300
@@ -0,0 +1,25 @@
+#ifndef __LIBGENL_H__
+#define __LIBGENL_H__
+
+#include "libnetlink.h"
+
+#define GENL_DEFINE_REQUEST(req, hdrsize, bufsiz)			\
+struct {								\
+	struct nlmsghdr		n;					\
+	struct genlmsghdr	g;					\
+	char			buf[NLMSG_ALIGN(hdrsize) + bufsiz];	\
+} req
+
+#define GENL_INIT_REQUEST(req, family, hdrsize, ver, cmd_, flags)	\
+	do {								\
+		memset(&req, 0, sizeof(req));				\
+		req.n.nlmsg_type = family;				\
+		req.n.nlmsg_flags = flags;				\
+		req.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN + hdrsize);	\
+		req.g.cmd = cmd_;					\
+		req.g.version = ver;					\
+	} while (0)
+
+int libgenl_resolve_family(struct rtnl_handle *grth, const char *family);
+
+#endif /* __LIBGENL_H__ */
diff -urpN iproute2-3.5.1/include/linux/tcp_metrics.h iproute2-3.5.1-tcp_metrics/include/linux/tcp_metrics.h
--- iproute2-3.5.1/include/linux/tcp_metrics.h	1970-01-01 02:00:00.000000000 +0200
+++ iproute2-3.5.1-tcp_metrics/include/linux/tcp_metrics.h	2012-08-23 09:50:54.385569009 +0300
@@ -0,0 +1,54 @@
+/* tcp_metrics.h - TCP Metrics Interface */
+
+#ifndef _LINUX_TCP_METRICS_H
+#define _LINUX_TCP_METRICS_H
+
+#include <linux/types.h>
+
+/* NETLINK_GENERIC related info
+ */
+#define TCP_METRICS_GENL_NAME		"tcp_metrics"
+#define TCP_METRICS_GENL_VERSION	0x1
+
+enum tcp_metric_index {
+	TCP_METRIC_RTT,
+	TCP_METRIC_RTTVAR,
+	TCP_METRIC_SSTHRESH,
+	TCP_METRIC_CWND,
+	TCP_METRIC_REORDERING,
+
+	/* Always last.  */
+	__TCP_METRIC_MAX,
+};
+
+#define TCP_METRIC_MAX	(__TCP_METRIC_MAX - 1)
+
+enum {
+	TCP_METRICS_ATTR_UNSPEC,
+	TCP_METRICS_ATTR_ADDR_IPV4,		/* u32 */
+	TCP_METRICS_ATTR_ADDR_IPV6,		/* binary */
+	TCP_METRICS_ATTR_AGE,			/* msecs */
+	TCP_METRICS_ATTR_TW_TSVAL,		/* u32, raw, rcv tsval */
+	TCP_METRICS_ATTR_TW_TS_STAMP,		/* s32, sec age */
+	TCP_METRICS_ATTR_VALS,			/* nested +1, u32 */
+	TCP_METRICS_ATTR_FOPEN_MSS,		/* u16 */
+	TCP_METRICS_ATTR_FOPEN_SYN_DROPS,	/* u16, count of drops */
+	TCP_METRICS_ATTR_FOPEN_SYN_DROP_TS,	/* msecs age */
+	TCP_METRICS_ATTR_FOPEN_COOKIE,		/* binary */
+
+	__TCP_METRICS_ATTR_MAX,
+};
+
+#define TCP_METRICS_ATTR_MAX	(__TCP_METRICS_ATTR_MAX - 1)
+
+enum {
+	TCP_METRICS_CMD_UNSPEC,
+	TCP_METRICS_CMD_GET,
+	TCP_METRICS_CMD_DEL,
+
+	__TCP_METRICS_CMD_MAX,
+};
+
+#define TCP_METRICS_CMD_MAX	(__TCP_METRICS_CMD_MAX - 1)
+
+#endif /* _LINUX_TCP_METRICS_H */
diff -urpN iproute2-3.5.1/ip/Makefile iproute2-3.5.1-tcp_metrics/ip/Makefile
--- iproute2-3.5.1/ip/Makefile	2012-08-13 18:13:58.000000000 +0300
+++ iproute2-3.5.1-tcp_metrics/ip/Makefile	2012-09-04 00:58:57.434883914 +0300
@@ -3,7 +3,7 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o ipr
     ipmaddr.o ipmonitor.o ipmroute.o ipprefix.o iptuntap.o \
     ipxfrm.o xfrm_state.o xfrm_policy.o xfrm_monitor.o \
     iplink_vlan.o link_veth.o link_gre.o iplink_can.o \
-    iplink_macvlan.o iplink_macvtap.o ipl2tp.o
+    iplink_macvlan.o iplink_macvtap.o ipl2tp.o tcp_metrics.o
 
 RTMONOBJ=rtmon.o
 
diff -urpN iproute2-3.5.1/ip/ip.c iproute2-3.5.1-tcp_metrics/ip/ip.c
--- iproute2-3.5.1/ip/ip.c	2012-08-13 18:13:58.000000000 +0300
+++ iproute2-3.5.1-tcp_metrics/ip/ip.c	2012-08-23 10:21:20.917653464 +0300
@@ -45,7 +45,7 @@ static void usage(void)
 "       ip [ -force ] -batch filename\n"
 "where  OBJECT := { link | addr | addrlabel | route | rule | neigh | ntable |\n"
 "                   tunnel | tuntap | maddr | mroute | mrule | monitor | xfrm |\n"
-"                   netns | l2tp }\n"
+"                   netns | l2tp | tcp_metrics }\n"
 "       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n"
 "                    -f[amily] { inet | inet6 | ipx | dnet | link } |\n"
 "                    -l[oops] { maximum-addr-flush-attempts } |\n"
@@ -78,6 +78,8 @@ static const struct cmd {
 	{ "tunl",	do_iptunnel },
 	{ "tuntap",	do_iptuntap },
 	{ "tap",	do_iptuntap },
+	{ "tcpmetrics",	do_tcp_metrics },
+	{ "tcp_metrics",do_tcp_metrics },
 	{ "monitor",	do_ipmonitor },
 	{ "xfrm",	do_xfrm },
 	{ "mroute",	do_multiroute },
diff -urpN iproute2-3.5.1/ip/ip_common.h iproute2-3.5.1-tcp_metrics/ip/ip_common.h
--- iproute2-3.5.1/ip/ip_common.h	2012-08-13 18:13:58.000000000 +0300
+++ iproute2-3.5.1-tcp_metrics/ip/ip_common.h	2012-08-23 10:19:11.005647457 +0300
@@ -42,6 +42,7 @@ extern int do_multirule(int argc, char *
 extern int do_netns(int argc, char **argv);
 extern int do_xfrm(int argc, char **argv);
 extern int do_ipl2tp(int argc, char **argv);
+extern int do_tcp_metrics(int argc, char **argv);
 
 static inline int rtm_get_table(struct rtmsg *r, struct rtattr **tb)
 {
diff -urpN iproute2-3.5.1/ip/tcp_metrics.c iproute2-3.5.1-tcp_metrics/ip/tcp_metrics.c
--- iproute2-3.5.1/ip/tcp_metrics.c	1970-01-01 02:00:00.000000000 +0200
+++ iproute2-3.5.1-tcp_metrics/ip/tcp_metrics.c	2012-09-04 01:12:19.706921106 +0300
@@ -0,0 +1,434 @@
+/*
+ * tcp_metrics.c	"ip tcp_metrics/tcpmetrics"
+ *
+ *		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;
+ *
+ * Authors:	Julian Anastasov <ja@ssi.bg>, August 2012
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <linux/if.h>
+
+#include <linux/genetlink.h>
+#include <linux/tcp_metrics.h>
+
+#include "utils.h"
+#include "ip_common.h"
+#include "libgenl.h"
+
+static void usage(void)
+{
+	fprintf(stderr, "Usage: ip tcp_metrics/tcpmetrics { COMMAND | help }\n");
+	fprintf(stderr, "       ip tcp_metrics { show | flush } SELECTOR\n");
+	fprintf(stderr, "       ip tcp_metrics delete [ address ] ADDRESS\n");
+	fprintf(stderr, "SELECTOR := [ [ address ] PREFIX ]\n");
+	exit(-1);
+}
+
+/* netlink socket */
+static struct rtnl_handle grth = { .fd = -1 };
+static int genl_family = -1;
+
+
+#define INIT_GENL_ACTION(req, cmd, ack)					\
+	GENL_INIT_REQUEST(req, genl_family, 0,				\
+			  TCP_METRICS_GENL_VERSION, cmd,		\
+			  NLM_F_REQUEST | ((ack) ? NLM_F_ACK : 0))
+
+#define INIT_GENL_DUMP(req)						\
+	GENL_INIT_REQUEST(req, genl_family, 0,				\
+			  TCP_METRICS_GENL_VERSION,			\
+			  TCP_METRICS_CMD_GET,				\
+			  NLM_F_DUMP | NLM_F_REQUEST)
+
+#define CMD_LIST	0x0001	/* list, lst, show		*/
+#define CMD_DEL		0x0002	/* delete, remove		*/
+#define CMD_FLUSH	0x0004	/* flush			*/
+
+static struct {
+	char	*name;
+	int	code;
+} cmds[] = {
+	{	"list",		CMD_LIST	},
+	{	"lst",		CMD_LIST	},
+	{	"show",		CMD_LIST	},
+	{	"delete",	CMD_DEL		},
+	{	"remove",	CMD_DEL		},
+	{	"flush",	CMD_FLUSH	},
+};
+
+static char *metric_name[TCP_METRIC_MAX + 1] = {
+	[TCP_METRIC_RTT]		= "rtt",
+	[TCP_METRIC_RTTVAR]		= "rttvar",
+	[TCP_METRIC_SSTHRESH]		= "ssthresh",
+	[TCP_METRIC_CWND]		= "cwnd",
+	[TCP_METRIC_REORDERING]		= "reordering",
+};
+
+static struct
+{
+	int flushed;
+	char *flushb;
+	int flushp;
+	int flushe;
+	int cmd;
+	inet_prefix addr;
+} f;
+
+static int flush_update(void)
+{
+	if (rtnl_send_check(&grth, f.flushb, f.flushp) < 0) {
+		perror("Failed to send flush request\n");
+		return -1;
+	}
+	f.flushp = 0;
+	return 0;
+}
+
+static int process_msg(const struct sockaddr_nl *who, struct nlmsghdr *n,
+		       void *arg)
+{
+	FILE *fp = (FILE *) arg;
+	struct genlmsghdr *ghdr;
+	struct rtattr *attrs[TCP_METRICS_ATTR_MAX + 1], *a;
+	int len = n->nlmsg_len;
+	char abuf[256];
+	inet_prefix addr;
+	int family, i, atype;
+
+	if (n->nlmsg_type != genl_family)
+		return -1;
+
+	len -= NLMSG_LENGTH(GENL_HDRLEN);
+	if (len < 0)
+		return -1;
+
+	ghdr = NLMSG_DATA(n);
+	if (ghdr->cmd != TCP_METRICS_CMD_GET)
+		return 0;
+
+	parse_rtattr(attrs, TCP_METRICS_ATTR_MAX, (void *) ghdr + GENL_HDRLEN,
+		     len);
+
+	a = attrs[TCP_METRICS_ATTR_ADDR_IPV4];
+	if (a) {
+		if (f.addr.family && f.addr.family != AF_INET)
+			return 0;
+		memcpy(&addr.data, RTA_DATA(a), 4);
+		addr.bytelen = 4;
+		family = AF_INET;
+		atype = TCP_METRICS_ATTR_ADDR_IPV4;
+	} else {
+		a = attrs[TCP_METRICS_ATTR_ADDR_IPV6];
+		if (a) {
+			if (f.addr.family && f.addr.family != AF_INET6)
+				return 0;
+			memcpy(&addr.data, RTA_DATA(a), 16);
+			addr.bytelen = 16;
+			family = AF_INET6;
+			atype = TCP_METRICS_ATTR_ADDR_IPV6;
+		} else
+			return 0;
+	}
+
+	if (f.addr.family && f.addr.bitlen >= 0 &&
+	    inet_addr_match(&addr, &f.addr, f.addr.bitlen))
+		return 0;
+
+	if (f.flushb) {
+		struct nlmsghdr *fn;
+		GENL_DEFINE_REQUEST(req2, 0, 128);
+
+		INIT_GENL_ACTION(req2, TCP_METRICS_CMD_DEL, 0);
+		addattr_l(&req2.n, sizeof(req2), atype, &addr.data,
+			  addr.bytelen);
+
+		if (NLMSG_ALIGN(f.flushp) + req2.n.nlmsg_len > f.flushe) {
+			if (flush_update())
+				return -1;
+		}
+		fn = (struct nlmsghdr *) (f.flushb + NLMSG_ALIGN(f.flushp));
+		memcpy(fn, &req2.n, req2.n.nlmsg_len);
+		fn->nlmsg_seq = ++grth.seq;
+		f.flushp = (((char *) fn) + req2.n.nlmsg_len) - f.flushb;
+		f.flushed++;
+		if (show_stats < 2)
+			return 0;
+	}
+
+	if (f.cmd & (CMD_DEL | CMD_FLUSH))
+		fprintf(fp, "Deleted ");
+
+	fprintf(fp, "%s",
+		format_host(family, RTA_PAYLOAD(a), &addr.data,
+			    abuf, sizeof(abuf)));
+
+	a = attrs[TCP_METRICS_ATTR_AGE];
+	if (a) {
+		__u64 val = rta_getattr_u64(a);
+
+		fprintf(fp, " age %llu.%03llusec",
+			val / 1000, val % 1000);
+	}
+
+	a = attrs[TCP_METRICS_ATTR_TW_TS_STAMP];
+	if (a) {
+		__s32 val = (__s32) rta_getattr_u32(a);
+		__u32 tsval;
+
+		a = attrs[TCP_METRICS_ATTR_TW_TSVAL];
+		tsval = a ? rta_getattr_u32(a) : 0;
+		fprintf(fp, " tw_ts %u/%dsec ago", tsval, val);
+	}
+
+	a = attrs[TCP_METRICS_ATTR_VALS];
+	if (a) {
+		struct rtattr *m[TCP_METRIC_MAX + 1 + 1];
+
+		parse_rtattr_nested(m, TCP_METRIC_MAX + 1, a);
+
+		for (i = 0; i < TCP_METRIC_MAX + 1; i++) {
+			__u32 val;
+
+			a = m[i + 1];
+			if (!a)
+				continue;
+			if (metric_name[i])
+				fprintf(fp, " %s ", metric_name[i]);
+			else
+				fprintf(fp, " metric_%d ", i);
+			val = rta_getattr_u32(a);
+			switch (i) {
+			case TCP_METRIC_RTT:
+			case TCP_METRIC_RTTVAR:
+				fprintf(fp, "%ums", val);
+				break;
+			case TCP_METRIC_SSTHRESH:
+			case TCP_METRIC_CWND:
+			case TCP_METRIC_REORDERING:
+			default:
+				fprintf(fp, "%u", val);
+				break;
+			}
+		}
+	}
+
+	a = attrs[TCP_METRICS_ATTR_FOPEN_MSS];
+	if (a)
+		fprintf(fp, " fo_mss %u", rta_getattr_u16(a));
+
+	a = attrs[TCP_METRICS_ATTR_FOPEN_SYN_DROPS];
+	if (a) {
+		__u16 syn_loss = rta_getattr_u16(a);
+		__u64 ts;
+
+		a = attrs[TCP_METRICS_ATTR_FOPEN_SYN_DROP_TS];
+		ts = a ? rta_getattr_u64(a) : 0;
+
+		fprintf(fp, " fo_syn_drops %u/%llu.%03llusec ago",
+			syn_loss, ts / 1000, ts % 1000);
+	}
+
+	a = attrs[TCP_METRICS_ATTR_FOPEN_COOKIE];
+	if (a) {
+		char cookie[32 + 1];
+		unsigned char *ptr = RTA_DATA(a);
+		int i, max = RTA_PAYLOAD(a);
+
+		if (max > 16)
+			max = 16;
+		cookie[0] = 0;
+		for (i = 0; i < max; i++)
+			sprintf(cookie + i + i, "%02x", ptr[i]);
+		fprintf(fp, " fo_cookie %s", cookie);
+	}
+
+	fprintf(fp, "\n");
+
+	fflush(fp);
+	return 0;
+}
+
+static int tcpm_do_cmd(int cmd, int argc, char **argv)
+{
+	GENL_DEFINE_REQUEST(req, 0, 1024);
+	int atype = -1;
+	int code, ack;
+
+	memset(&f, 0, sizeof(f));
+	f.addr.bitlen = -1;
+	f.addr.family = preferred_family;
+
+	switch (preferred_family) {
+	case AF_UNSPEC:
+	case AF_INET:
+	case AF_INET6:
+		break;
+	default:
+		fprintf(stderr, "Unsupported family:%d\n", preferred_family);
+		return -1;
+	}
+
+	for (; argc > 0; argc--, argv++) {
+		char *who = "address";
+
+		if (strcmp(*argv, "addr") == 0 ||
+		    strcmp(*argv, "address") == 0) {
+			who = *argv;
+			NEXT_ARG();
+		}
+		if (matches(*argv, "help") == 0)
+			usage();
+		if (f.addr.bitlen >= 0)
+			duparg2(who, *argv);
+
+		get_prefix(&f.addr, *argv, preferred_family);
+		if (f.addr.bytelen && f.addr.bytelen * 8 == f.addr.bitlen) {
+			if (f.addr.family == AF_INET)
+				atype = TCP_METRICS_ATTR_ADDR_IPV4;
+			else if (f.addr.family == AF_INET6)
+				atype = TCP_METRICS_ATTR_ADDR_IPV6;
+		}
+		if ((CMD_DEL & cmd) && atype < 0) {
+			fprintf(stderr, "Error: a specific IP address is expected rather than \"%s\"\n",
+				*argv);
+			return -1;
+		}
+
+		argc--; argv++;
+	}
+
+	if (cmd == CMD_DEL && atype < 0)
+		missarg("address");
+
+	/* flush for exact address ? Single del */
+	if (cmd == CMD_FLUSH && atype >= 0)
+		cmd = CMD_DEL;
+	/* flush for all addresses ? Single del without address */
+	if (cmd == CMD_FLUSH && f.addr.bitlen <= 0 &&
+	    preferred_family == AF_UNSPEC) {
+		cmd = CMD_DEL;
+		code = TCP_METRICS_CMD_DEL;
+		ack = 1;
+	} else if (cmd == CMD_DEL) {
+		code = TCP_METRICS_CMD_DEL;
+		ack = 1;
+	} else {	/* CMD_FLUSH, CMD_LIST */
+		code = TCP_METRICS_CMD_GET;
+		ack = 0;
+	}
+
+	if (genl_family < 0) {
+		if (rtnl_open_byproto(&grth, 0, NETLINK_GENERIC) < 0) {
+			fprintf(stderr, "Cannot open generic netlink socket\n");
+			exit(1);
+		}
+		genl_family = libgenl_resolve_family(&grth,
+						     TCP_METRICS_GENL_NAME);
+		if (genl_family < 0)
+			exit(1);
+	}
+
+	if (!(cmd & CMD_FLUSH) && (atype >= 0 || (cmd & CMD_DEL))) {
+		INIT_GENL_ACTION(req, code, ack);
+		if (atype >= 0)
+			addattr_l(&req.n, sizeof(req), atype, &f.addr.data,
+				  f.addr.bytelen);
+	} else {
+		INIT_GENL_DUMP(req);
+	}
+
+	f.cmd = cmd;
+	if (cmd & CMD_FLUSH) {
+		int round = 0;
+		char flushb[4096-512];
+
+		f.flushb = flushb;
+		f.flushp = 0;
+		f.flushe = sizeof(flushb);
+
+		for (;;) {
+			req.n.nlmsg_seq = grth.dump = ++grth.seq;
+			if (rtnl_send(&grth, &req, req.n.nlmsg_len) < 0) {
+				perror("Failed to send flush request");
+				exit(1);
+			}
+			f.flushed = 0;
+			if (rtnl_dump_filter(&grth, process_msg, stdout) < 0) {
+				fprintf(stderr, "Flush terminated\n");
+				exit(1);
+			}
+			if (f.flushed == 0) {
+				if (round == 0) {
+					fprintf(stderr, "Nothing to flush.\n");
+				} else if (show_stats)
+					printf("*** Flush is complete after %d round%s ***\n",
+					       round, round > 1 ? "s" : "");
+				fflush(stdout);
+				return 0;
+			}
+			round++;
+			if (flush_update() < 0)
+				exit(1);
+			if (show_stats) {
+				printf("\n*** Round %d, deleting %d entries ***\n",
+				       round, f.flushed);
+				fflush(stdout);
+			}
+		}
+		return 0;
+	}
+
+	if (ack) {
+		if (rtnl_talk(&grth, &req.n, 0, 0, NULL) < 0)
+			return -2;
+	} else if (atype >= 0) {
+		if (rtnl_talk(&grth, &req.n, 0, 0, &req.n) < 0)
+			return -2;
+		if (process_msg(NULL, &req.n, stdout) < 0) {
+			fprintf(stderr, "Dump terminated\n");
+			exit(1);
+		}
+	} else {
+		req.n.nlmsg_seq = grth.dump = ++grth.seq;
+		if (rtnl_send(&grth, &req, req.n.nlmsg_len) < 0) {
+			perror("Failed to send dump request");
+			exit(1);
+		}
+
+		if (rtnl_dump_filter(&grth, process_msg, stdout) < 0) {
+			fprintf(stderr, "Dump terminated\n");
+			exit(1);
+		}
+	}
+	return 0;
+}
+
+int do_tcp_metrics(int argc, char **argv)
+{
+	int i;
+
+	if (argc < 1)
+		return tcpm_do_cmd(CMD_LIST, 0, NULL);
+	for (i = 0; i < ARRAY_SIZE(cmds); i++) {
+		if (matches(argv[0], cmds[i].name) == 0)
+			return tcpm_do_cmd(cmds[i].code, argc-1, argv+1);
+	}
+	if (matches(argv[0], "help") == 0)
+		usage();
+
+	fprintf(stderr, "Command \"%s\" is unknown, "
+			"try \"ip tcp_metrics help\".\n", *argv);
+	exit(-1);
+}
+
diff -urpN iproute2-3.5.1/lib/Makefile iproute2-3.5.1-tcp_metrics/lib/Makefile
--- iproute2-3.5.1/lib/Makefile	2012-08-13 18:13:58.000000000 +0300
+++ iproute2-3.5.1-tcp_metrics/lib/Makefile	2012-09-04 00:58:43.950883370 +0300
@@ -2,7 +2,7 @@ CFLAGS += -fPIC
 
 UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o
 
-NLOBJ=ll_map.o libnetlink.o
+NLOBJ=libgenl.o ll_map.o libnetlink.o
 
 all: libnetlink.a libutil.a
 
diff -urpN iproute2-3.5.1/lib/libgenl.c iproute2-3.5.1-tcp_metrics/lib/libgenl.c
--- iproute2-3.5.1/lib/libgenl.c	1970-01-01 02:00:00.000000000 +0200
+++ iproute2-3.5.1-tcp_metrics/lib/libgenl.c	2012-09-04 01:10:05.794915224 +0300
@@ -0,0 +1,65 @@
+/*
+ * libgenl.c	GENL library
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <linux/genetlink.h>
+#include "libgenl.h"
+
+static int libgenl_parse_getfamily(struct nlmsghdr *nlh)
+{
+	struct rtattr *tb[CTRL_ATTR_MAX + 1];
+	struct genlmsghdr *ghdr = NLMSG_DATA(nlh);
+	int len = nlh->nlmsg_len;
+	struct rtattr *attrs;
+
+	if (nlh->nlmsg_type != GENL_ID_CTRL) {
+		fprintf(stderr, "Not a controller message, nlmsg_len=%d "
+			"nlmsg_type=0x%x\n", nlh->nlmsg_len, nlh->nlmsg_type);
+		return -1;
+	}
+
+	len -= NLMSG_LENGTH(GENL_HDRLEN);
+
+	if (len < 0) {
+		fprintf(stderr, "wrong controller message len %d\n", len);
+		return -1;
+	}
+
+	if (ghdr->cmd != CTRL_CMD_NEWFAMILY) {
+		fprintf(stderr, "Unknown controller command %d\n", ghdr->cmd);
+		return -1;
+	}
+
+	attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN);
+	parse_rtattr(tb, CTRL_ATTR_MAX, attrs, len);
+
+	if (tb[CTRL_ATTR_FAMILY_ID] == NULL) {
+		fprintf(stderr, "Missing family id TLV\n");
+		return -1;
+	}
+
+	return rta_getattr_u16(tb[CTRL_ATTR_FAMILY_ID]);
+}
+
+int libgenl_resolve_family(struct rtnl_handle *grth, const char *family)
+{
+	GENL_DEFINE_REQUEST(req, 0, 1024);
+
+	GENL_INIT_REQUEST(req, GENL_ID_CTRL, 0, 0, CTRL_CMD_GETFAMILY,
+			  NLM_F_REQUEST);
+
+	addattr_l(&req.n, 1024, CTRL_ATTR_FAMILY_NAME,
+		  family, strlen(family) + 1);
+
+	if (rtnl_talk(grth, &req.n, 0, 0, &req.n) < 0) {
+		fprintf(stderr, "Error talking to the kernel\n");
+		return -2;
+	}
+
+	return libgenl_parse_getfamily(&req.n);
+}
+
diff -urpN iproute2-3.5.1/man/man8/Makefile iproute2-3.5.1-tcp_metrics/man/man8/Makefile
--- iproute2-3.5.1/man/man8/Makefile	2012-08-13 18:13:58.000000000 +0300
+++ iproute2-3.5.1-tcp_metrics/man/man8/Makefile	2012-08-23 14:45:12.506385476 +0300
@@ -7,7 +7,8 @@ MAN8PAGES = $(TARGETS) ip.8 arpd.8 lnsta
 	bridge.8 rtstat.8 ctstat.8 nstat.8 routef.8 \
 	ip-tunnel.8 ip-rule.8 ip-ntable.8 \
 	ip-monitor.8 tc-stab.8 tc-hfsc.8 ip-xfrm.8 ip-netns.8 \
-	ip-neighbour.8 ip-mroute.8 ip-maddress.8 ip-addrlabel.8 
+	ip-neighbour.8 ip-mroute.8 ip-maddress.8 ip-addrlabel.8 \
+	ip-tcp_metrics.8
 
 
 all: $(TARGETS)
diff -urpN iproute2-3.5.1/man/man8/ip-tcp_metrics.8 iproute2-3.5.1-tcp_metrics/man/man8/ip-tcp_metrics.8
--- iproute2-3.5.1/man/man8/ip-tcp_metrics.8	1970-01-01 02:00:00.000000000 +0200
+++ iproute2-3.5.1-tcp_metrics/man/man8/ip-tcp_metrics.8	2012-08-25 17:37:30.868321617 +0300
@@ -0,0 +1,143 @@
+.TH "IP\-TCP_METRICS" 8 "23 Aug 2012" "iproute2" "Linux"
+.SH "NAME"
+ip-tcp_metrics \- management for TCP Metrics
+.SH "SYNOPSIS"
+.sp
+.ad l
+.in +8
+.ti -8
+.B ip
+.RI "[ " OPTIONS " ]"
+.B tcp_metrics
+.RI "{ " COMMAND " | "
+.BR help " }"
+.sp
+
+.ti -8
+.BR "ip tcp_metrics" " { " show " | " flush " }
+.IR SELECTOR
+
+.ti -8
+.BR "ip tcp_metrics delete " [ " address " ]
+.IR ADDRESS
+
+.ti -8
+.IR SELECTOR " := " 
+.RB "[ [ " address " ] "
+.IR PREFIX " ]"
+
+.SH "DESCRIPTION"
+.B ip tcp_metrics
+is used to manipulate entries in the kernel that keep TCP information
+for IPv4 and IPv6 destinations. The entries are created when
+TCP sockets want to share information for destinations and are
+stored in a cache keyed by the destination address. The saved
+information may include values for metrics (initially obtained from
+routes), recent TSVAL for TIME-WAIT recycling purposes, state for the
+Fast Open feature, etc.
+For performance reasons the cache can not grow above configured limit
+and the older entries are replaced with fresh information, sometimes
+reclaimed and used for new destinations. The kernel never removes
+entries, they can be flushed only with this tool.
+
+.SS ip tcp_metrics show - show cached entries
+
+.TP
+.BI address " PREFIX " (default)
+IPv4/IPv6 prefix or address. If no prefix is provided all entries are shown.
+
+.LP
+The output may contain the following information:
+
+.BI age " <S.MMM>" sec
+- time after the entry was created, reset or updated with metrics
+from sockets. The entry is reset and refreshed on use with metrics from
+route if the metrics are not updated in last hour. Not all cached values
+reset the age on update.
+
+.BI cwnd " <N>"
+- CWND metric value
+
+.BI fo_cookie " <HEX-STRING>"
+- Cookie value received in SYN-ACK to be used by Fast Open for next SYNs
+
+.BI fo_mss " <N>"
+- MSS value received in SYN-ACK to be used by Fast Open for next SYNs
+
+.BI fo_syn_drops " <N>/<S.MMM>" "sec ago"
+- Number of drops of initial outgoing Fast Open SYNs with data
+detected by monitoring the received SYN-ACK after SYN retransmission.
+The seconds show the time after last SYN drop and together with
+the drop count can be used to disable Fast Open for some time.
+
+.BI reordering " <N>"
+- Reordering metric value
+
+.BI rtt " <N>" ms
+- RTT metric value
+
+.BI rttvar " <N>" ms
+- RTTVAR metric value
+
+.BI ssthresh " <SSTHRESH>"
+- SSTHRESH metric value
+
+.BI tw_ts " <TSVAL>/<SEC>" "sec ago"
+- recent TSVAL and the seconds after saving it into TIME-WAIT socket
+
+.SS ip tcp_metrics delete - delete single entry
+
+.TP
+.BI address " ADDRESS " (default)
+IPv4/IPv6 address. The address is a required argument.
+
+.SS ip tcp_metrics flush - flush entries
+This command flushes the entries selected by some criteria.
+
+.PP
+This command has the same arguments as
+.B show.
+
+.SH "EXAMPLES"
+.PP
+ip tcp_metrics show address 192.168.0.0/24
+.RS 4
+Shows the entries for destinations from subnet
+.RE
+.PP
+ip tcp_metrics show 192.168.0.0/24
+.RS 4
+The same but address keyword is optional
+.RE
+.PP
+ip tcp_metrics
+.RS 4
+Show all is the default action
+.RE
+.PP
+ip tcp_metrics delete 192.168.0.1
+.RS 4
+Removes the entry for 192.168.0.1 from cache.
+.RE
+.PP
+ip tcp_metrics flush 192.168.0.0/24
+.RS 4
+Removes entries for destinations from subnet
+.RE
+.PP
+ip tcp_metrics flush all
+.RS 4
+Removes all entries from cache
+.RE
+.PP
+ip -6 tcp_metrics flush all
+.RS 4
+Removes all IPv6 entries from cache keeping the IPv4 entries.
+.RE
+
+.SH SEE ALSO
+.br
+.BR ip (8)
+
+.SH AUTHOR
+Original Manpage by Julian Anastasov <ja@ssi.bg>
diff -urpN iproute2-3.5.1/man/man8/ip.8 iproute2-3.5.1-tcp_metrics/man/man8/ip.8
--- iproute2-3.5.1/man/man8/ip.8	2012-08-13 18:13:58.000000000 +0300
+++ iproute2-3.5.1-tcp_metrics/man/man8/ip.8	2012-08-23 10:28:12.541672495 +0300
@@ -15,7 +15,7 @@ ip \- show / manipulate routing, devices
 .IR OBJECT " := { "
 .BR link " | " addr " | " addrlabel " | " route " | " rule " | " neigh " | "\
  ntable " | " tunnel " | " tuntap " | " maddr " | "  mroute " | " mrule " | "\
- monitor " | " xfrm " | " netns " | "  l2tp " }"
+ monitor " | " xfrm " | " netns " | "  l2tp " | "  tcp_metrics " }"
 .sp
 
 .ti -8
@@ -156,6 +156,10 @@ host addresses.
 - rule in routing policy database.
 
 .TP
+.B tcp_metrics/tcpmetrics
+- manage TCP Metrics
+
+.TP
 .B tunnel
 - tunnel over IP.
 
@@ -215,6 +219,7 @@ was written by Alexey N. Kuznetsov and a
 .BR ip-ntable (8),
 .BR ip-route (8),
 .BR ip-rule (8),
+.BR ip-tcp_metrics (8),
 .BR ip-tunnel (8),
 .BR ip-xfrm (8)
 .br

^ permalink raw reply

* [PATCH v3 3/3] iproute2: use libgenl for ipl2tp
From: Julian Anastasov @ 2012-09-04 21:03 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Stephen Hemminger
In-Reply-To: <1346792597-2427-1-git-send-email-ja@ssi.bg>

	Use the common code from libgenl.c

Signed-off-by: Julian Anastasov <ja@ssi.bg>
---

diff -urp iproute2-3.5.1-tcp_metrics/ip/ipl2tp.c iproute2-3.5.1-ipl2tp-genl/ip/ipl2tp.c
--- iproute2-3.5.1-tcp_metrics/ip/ipl2tp.c	2012-08-13 18:13:58.000000000 +0300
+++ iproute2-3.5.1-ipl2tp-genl/ip/ipl2tp.c	2012-09-04 01:40:55.775000653 +0300
@@ -25,6 +25,7 @@
 
 #include <linux/genetlink.h>
 #include <linux/l2tp.h>
+#include "libgenl.h"
 
 #include "utils.h"
 #include "ip_common.h"
@@ -747,67 +748,6 @@ static int do_show(int argc, char **argv
 	return 0;
 }
 
-static int genl_parse_getfamily(struct nlmsghdr *nlh)
-{
-	struct rtattr *tb[CTRL_ATTR_MAX + 1];
-	struct genlmsghdr *ghdr = NLMSG_DATA(nlh);
-	int len = nlh->nlmsg_len;
-	struct rtattr *attrs;
-
-	if (nlh->nlmsg_type != GENL_ID_CTRL) {
-		fprintf(stderr, "Not a controller message, nlmsg_len=%d "
-			"nlmsg_type=0x%x\n", nlh->nlmsg_len, nlh->nlmsg_type);
-		return -1;
-	}
-
-	if (ghdr->cmd != CTRL_CMD_NEWFAMILY) {
-		fprintf(stderr, "Unknown controller command %d\n", ghdr->cmd);
-		return -1;
-	}
-
-	len -= NLMSG_LENGTH(GENL_HDRLEN);
-
-	if (len < 0) {
-		fprintf(stderr, "wrong controller message len %d\n", len);
-		return -1;
-	}
-
-	attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN);
-	parse_rtattr(tb, CTRL_ATTR_MAX, attrs, len);
-
-	if (tb[CTRL_ATTR_FAMILY_ID] == NULL) {
-		fprintf(stderr, "Missing family id TLV\n");
-		return -1;
-	}
-
-	return rta_getattr_u16(tb[CTRL_ATTR_FAMILY_ID]);
-}
-
-int genl_ctrl_resolve_family(const char *family)
-{
-	struct {
-		struct nlmsghdr         n;
-		struct genlmsghdr	g;
-		char                    buf[1024];
-	} req;
-
-	memset(&req, 0, sizeof(req));
-	req.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
-	req.n.nlmsg_flags = NLM_F_REQUEST;
-	req.n.nlmsg_type = GENL_ID_CTRL;
-	req.g.cmd = CTRL_CMD_GETFAMILY;
-
-	addattr_l(&req.n, 1024, CTRL_ATTR_FAMILY_NAME,
-		  family, strlen(family) + 1);
-
-	if (rtnl_talk(&genl_rth, &req.n, 0, 0, &req.n) < 0) {
-		fprintf(stderr, "Error talking to the kernel\n");
-		return -2;
-	}
-
-	return genl_parse_getfamily(&req.n);
-}
-
 int do_ipl2tp(int argc, char **argv)
 {
 	if (genl_family < 0) {
@@ -816,7 +756,8 @@ int do_ipl2tp(int argc, char **argv)
 			exit(1);
 		}
 
-		genl_family = genl_ctrl_resolve_family(L2TP_GENL_NAME);
+		genl_family = libgenl_resolve_family(&genl_rth,
+						     L2TP_GENL_NAME);
 		if (genl_family < 0)
 			exit(1);
 	}

^ permalink raw reply

* Re: [PATCH V2 09/12] net/eipoib: Add main driver functionality
From: Michael S. Tsirkin @ 2012-09-04 21:21 UTC (permalink / raw)
  To: Or Gerlitz
  Cc: Eric W. Biederman, Or Gerlitz, davem, roland, netdev, sean.hefty,
	Erez Shitrit, Ali Ayoub, Doug Ledford
In-Reply-To: <CAJZOPZJdmDY8rqHJ+jeuG2rLMj9CnwnemkBG=nxD=z9JBFQCRQ@mail.gmail.com>

On Tue, Sep 04, 2012 at 09:50:09PM +0300, Or Gerlitz wrote:
> > And just to stress the point, document the limitations as well.
> 
> sure, not that I see concrete limitations for the **user** at this point, but
> if there are such, will put them clearly written.

Hmm, I'm afraid you mistook a short list of some major
bugs that jumped out at me for an exhaustive list.
This was not intended as such.

Here's how to find some of the limitations in your design
1. look through list archives. Some where pointed out to you
2. list everything ethernet does that you dont, or do differently
3. list everything ipoib does that you don't or do differently
4. list any extra setup work required on behalf of the user
5. check various overheads, compare with native ipoib and alternatives
   such as routing
6. if you still have an empty list of limitations and disadvantages,
   look again :)

The point is to have documentation that is useful both
for reviewers - so they can know which bugs are known
and which need to be reported; and for users -
who should not be expected to be familiar with
internals of your implementation.

-- 
MST

^ permalink raw reply

* Re: [PATCH 2/3] ipvs: Fix faulty IPv6 extension header handling in IPVS
From: Jesper Dangaard Brouer @ 2012-09-04 21:25 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: netdev, Hans Schillstrom, lvs-devel, Julian Anastasov,
	Simon Horman, Wensong Zhang, netfilter-devel
In-Reply-To: <Pine.GSO.4.63.1208262311110.16771@stinky-local.trash.net>

On Mon, 20 Aug 2012, Jesper Dangaard Brouer wrote:

[cut]

> This patch contains a lot of API changes.  This is done, to avoid
> the costly scan of finding the IPv6 headers, via ipv6_find_hdr().

(small correction ipv6_find_hdr() is not that costly for the general
case of no exthdrs)

> Finding the IPv6 headers is done as early as possible, and passed
> on as a pointer "struct ip_vs_iphdr *" to the affected functions.

This passing the "struct ip_vs_iphdr" actually makes sense.  It reminds
me of the way netfilter/iptables passes the xt_actions_param to each
rule.  Which contains the same information as ip_vs_iphdr.  (note ipvs
register at hooks at a lower level and don't get passed the
xt_actions_param).

Thus, perhaps we should keep these API changes.  Even if we decide to
optimize ipv6_find_hdr().  (as proposed by my RFC patch)

Perhaps we should consider adding a "family" to ip_vs_iphdr, as is done
in xt_actions_param.  This could help us, with collapsing IPv4 and IPv6
code, but i can see that other structs in IPVS carry this info already,
so not sure its relevant.



^ permalink raw reply

* Re: [PATCH v3 01/17] hashtable: introduce a small and naive hashtable
From: Pedro Alves @ 2012-09-04 21:51 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Mathieu Desnoyers, Sasha Levin, Tejun Heo, torvalds, akpm,
	linux-kernel, linux-mm, paul.gortmaker, davem, mingo, ebiederm,
	aarcange, ericvh, netdev, josh, eric.dumazet, axboe, agk,
	dm-devel, neilb, ccaulfie, teigland, Trond.Myklebust, bfields,
	fweisbec, jesse, venkat.x.venkatsubra, ejt, snitzer, edumazet,
	linux-nfs, dev, rds-devel, lw
In-Reply-To: <1346792345.27919.18.camel@gandalf.local.home>

On 09/04/2012 09:59 PM, Steven Rostedt wrote:
> On Tue, 2012-09-04 at 18:21 +0100, Pedro Alves wrote:
>> On 09/04/2012 06:17 PM, Steven Rostedt wrote:
>>> On Tue, 2012-09-04 at 17:40 +0100, Pedro Alves wrote:
>>>
>>>> BTW, you can also go a step further and remove the need to close with double }},
>>>> with something like:
>>>>
>>>> #define do_for_each_ftrace_rec(pg, rec)                                          \
>>>>         for (pg = ftrace_pages_start, rec = &pg->records[pg->index];             \
>>>>              pg && rec == &pg->records[pg->index];                               \
>>>>              pg = pg->next)                                                      \
>>>>           for (rec = pg->records; rec < &pg->records[pg->index]; rec++)
>>>>
>>>
>>> Yeah, but why bother? It's hidden in a macro, and the extra '{ }' shows
>>> that this is something "special".
>>
>> The point of both changes is that there's nothing special in the end
>> at all.  It all just works...
>>
> 
> It would still fail on a 'break'. The 'while' macro tells us that it is
> special, because in the end, it wont work.

Please explain why it would fail on a 'break'.

-- 
Pedro Alves

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

* Re: [PATCH v3 01/17] hashtable: introduce a small and naive hashtable
From: Steven Rostedt @ 2012-09-04 22:41 UTC (permalink / raw)
  To: Pedro Alves
  Cc: snitzer-H+wXaHxf7aLQT0dZR+AlfA, neilb-l3A5Bk7waGM,
	fweisbec-Re5JQEeQqe8AvxtiuMwx3w,
	Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA,
	bfields-uC3wQj2KruNg9hUCZPvPmw,
	paul.gortmaker-CWA4WttNNZF54TAoqtyWWQ,
	dm-devel-H+wXaHxf7aLQT0dZR+AlfA, agk-H+wXaHxf7aLQT0dZR+AlfA,
	aarcange-H+wXaHxf7aLQT0dZR+AlfA, rds-devel-N0ozoZBvEnrZJqsBc5GL+g,
	eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
	venkat.x.venkatsubra-QHcLZuEGTsvQT0dZR+AlfA,
	ccaulfie-H+wXaHxf7aLQT0dZR+AlfA, mingo-X9Un+BFzKDI,
	dev-yBygre7rU0TnMu66kgdUjQ, ericvh-Re5JQEeQqe8AvxtiuMwx3w,
	josh-iaAMLnmF4UmaiuxdJuQwMA, lw-BthXqXjhjHXQFUHtdCDX3A,
	Mathieu Desnoyers, Sasha Levin, axboe-tSWWG44O7X1aa/9Udqfwiw,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA, edumazet-hpIqsD4AKlfQT0dZR+AlfA,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, ejt-H+wXaHxf7aLQT0dZR+AlfA,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, Tejun Heo,
	teigland-H+wXaHxf7aLQT0dZR+AlfA,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <504677C8.3050801-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

On Tue, 2012-09-04 at 22:51 +0100, Pedro Alves wrote:
> On 09/04/2012 09:59 PM, Steven Rostedt wrote:
> > On Tue, 2012-09-04 at 18:21 +0100, Pedro Alves wrote:
> >> On 09/04/2012 06:17 PM, Steven Rostedt wrote:
> >>> On Tue, 2012-09-04 at 17:40 +0100, Pedro Alves wrote:
> >>>
> >>>> BTW, you can also go a step further and remove the need to close with double }},
> >>>> with something like:
> >>>>
> >>>> #define do_for_each_ftrace_rec(pg, rec)                                          \
> >>>>         for (pg = ftrace_pages_start, rec = &pg->records[pg->index];             \
> >>>>              pg && rec == &pg->records[pg->index];                               \
> >>>>              pg = pg->next)                                                      \
> >>>>           for (rec = pg->records; rec < &pg->records[pg->index]; rec++)
> >>>>
> >>>
> >>> Yeah, but why bother? It's hidden in a macro, and the extra '{ }' shows
> >>> that this is something "special".
> >>
> >> The point of both changes is that there's nothing special in the end
> >> at all.  It all just works...
> >>
> > 
> > It would still fail on a 'break'. The 'while' macro tells us that it is
> > special, because in the end, it wont work.
> 
> Please explain why it would fail on a 'break'.
> 

Ah, I missed the condition with the rec == &pg->records[pg->index]. But
if ftrace_pages_start is NULL, the rec = &pg->records[pg->index] will
fault.

You could do something like rec = pg ? &pg->records[pg->index] : NULL,
but IIRC, the comma operator does not guarantee order evaluation. That
is, the compiler is allowed to process "a , b" as "b; a;" and not "a;
b;".

-- Steve

^ permalink raw reply

* Re: [PATCH v3 01/17] hashtable: introduce a small and naive hashtable
From: Pedro Alves @ 2012-09-04 22:58 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Mathieu Desnoyers, Sasha Levin, Tejun Heo, torvalds, akpm,
	linux-kernel, linux-mm, paul.gortmaker, davem, mingo, ebiederm,
	aarcange, ericvh, netdev, josh, eric.dumazet, axboe, agk,
	dm-devel, neilb, ccaulfie, teigland, Trond.Myklebust, bfields,
	fweisbec, jesse, venkat.x.venkatsubra, ejt, snitzer, edumazet,
	linux-nfs, dev, rds-devel, lw
In-Reply-To: <1346798509.27919.25.camel@gandalf.local.home>

On 09/04/2012 11:41 PM, Steven Rostedt wrote:
> Ah, I missed the condition with the rec == &pg->records[pg->index]. But
> if ftrace_pages_start is NULL, the rec = &pg->records[pg->index] will
> fault.

Right.

> 
> You could do something like rec = pg ? &pg->records[pg->index] : NULL,

Right.

> but IIRC, the comma operator does not guarantee order evaluation. That
> is, the compiler is allowed to process "a , b" as "b; a;" and not "a;
> b;".

Not true.  The comma operator introduces a sequence point.  It's the comma
that separates function parameters that doesn't guarantee ordering.

-- 
Pedro Alves

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

* Re: [PATCH 15/25] netfilter: nf_nat: support IPv6 in SIP NAT helper
From: Eric W. Biederman @ 2012-09-04 23:14 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, davem, netdev
In-Reply-To: <1346716452-3080-16-git-send-email-pablo@netfilter.org>

pablo@netfilter.org writes:

> From: Patrick McHardy <kaber@trash.net>
>
> Add IPv6 support to the SIP NAT helper. There are no functional differences
> to IPv4 NAT, just different formats for addresses.

Am I missing something here?  It looks like you are implementing port
translation for ipv6.

Simple address translation I can understand.  Especially when it
conforms to RFC6296 and doesn't need to look beyond the addresses and
doesn't even need to recompute checksums.

I can understand having a policy that explicitly manglees various
aspects of a packet as it comes through.  Sometimes people have weird
local policies and need to do weird and peculiar things.

I can understand connection tracking, and have no problems with
connection tracking as it does not get in the way of protocol evolution.

However this looks like full automatic address and port translation like
we have with ipv4.


I can't understand implementiong port translation for ipv6.  We don't
have a shortage of addresses, so there is no need to share addresses.


There has been a lot of work done with with protocol design and figuring
out how to work through NAT boxes.  One of the most complete
descriptions is in RFC5245 ICE.

Frequently protocol designers suggest that ALGs like this not be used
because they get in the way of protocol enhancements like ICE that
provide more general ways to work through the challenges.

RFC5245 can handle any kind of common NAT except both sides doing prefix
translation.  As long as one side can predict the port on the other side
of the NAT device ICE can successfully establish a connection.

Please tell me I am missing something and you are not generalizing code
that breaks protocols without any known work around?

Given that RFC5245 is strongly suggested if not required for ipv6 sip
support I really fail to see why generalizing the sip nat code from ipv4
to ipv6 makes a bit of sense.

RFC6314 "NAT Traversal Practices for Client-Server SIP" may be
interesting for more background on what people are implementing.

As a statement of how protocol designers feel about ALGs section
18.6 of RFC5245 is interesting:

   ICE works best through ALGs when the signaling is run over TLS.  This
   prevents the ALG from manipulating the SDP messages and interfering
   with ICE operation.  Implementations that are expected to be deployed
   behind ALGs SHOULD provide for TLS transport of the SDP.


So I am trying to understand how IPv6 ALGs make sense in general, as
IPv6 prefix translation is checksum neutral so they are in general
unneeded.  And how IPv6 ALGs for sip make sense as the protocol
maintainers report that best results are had without ALGs.
My own experiments confirm that ALGs are not needed for SIP if
you have ICE implementations on both sides.

What am I missing?

Eric


> Signed-off-by: Patrick McHardy <kaber@trash.net>
> ---
>  include/linux/netfilter/nf_conntrack_sip.h |    9 +-
>  net/ipv4/netfilter/Kconfig                 |    5 -
>  net/ipv4/netfilter/Makefile                |    1 -
>  net/ipv4/netfilter/nf_nat_sip.c            |  580 --------------------------
>  net/netfilter/Kconfig                      |    5 +
>  net/netfilter/Makefile                     |    1 +
>  net/netfilter/nf_conntrack_sip.c           |   68 ++--
>  net/netfilter/nf_nat_sip.c                 |  609 ++++++++++++++++++++++++++++
>  8 files changed, 653 insertions(+), 625 deletions(-)
>  delete mode 100644 net/ipv4/netfilter/nf_nat_sip.c
>  create mode 100644 net/netfilter/nf_nat_sip.c
>
> diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h
> index 1afc669..387bdd0 100644
> --- a/include/linux/netfilter/nf_conntrack_sip.h
> +++ b/include/linux/netfilter/nf_conntrack_sip.h
> @@ -99,10 +99,8 @@ enum sip_header_types {
>  enum sdp_header_types {
>  	SDP_HDR_UNSPEC,
>  	SDP_HDR_VERSION,
> -	SDP_HDR_OWNER_IP4,
> -	SDP_HDR_CONNECTION_IP4,
> -	SDP_HDR_OWNER_IP6,
> -	SDP_HDR_CONNECTION_IP6,
> +	SDP_HDR_OWNER,
> +	SDP_HDR_CONNECTION,
>  	SDP_HDR_MEDIA,
>  };
>  
> @@ -111,7 +109,8 @@ extern unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb,
>  				       unsigned int dataoff,
>  				       const char **dptr,
>  				       unsigned int *datalen);
> -extern void (*nf_nat_sip_seq_adjust_hook)(struct sk_buff *skb, s16 off);
> +extern void (*nf_nat_sip_seq_adjust_hook)(struct sk_buff *skb,
> +					  unsigned int protoff, s16 off);
>  extern unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb,
>  					      unsigned int protoff,
>  					      unsigned int dataoff,
> diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
> index 52c4a87..30197f8 100644
> --- a/net/ipv4/netfilter/Kconfig
> +++ b/net/ipv4/netfilter/Kconfig
> @@ -242,11 +242,6 @@ config NF_NAT_H323
>  	depends on NF_CONNTRACK && NF_NAT_IPV4
>  	default NF_NAT_IPV4 && NF_CONNTRACK_H323
>  
> -config NF_NAT_SIP
> -	tristate
> -	depends on NF_CONNTRACK && NF_NAT_IPV4
> -	default NF_NAT_IPV4 && NF_CONNTRACK_SIP
> -
>  # mangle + specific targets
>  config IP_NF_MANGLE
>  	tristate "Packet mangling"
> diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
> index 8baa496..8914abf 100644
> --- a/net/ipv4/netfilter/Makefile
> +++ b/net/ipv4/netfilter/Makefile
> @@ -23,7 +23,6 @@ obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o
>  obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o
>  obj-$(CONFIG_NF_NAT_IRC) += nf_nat_irc.o
>  obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o
> -obj-$(CONFIG_NF_NAT_SIP) += nf_nat_sip.o
>  obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o
>  obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o
>  
> diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
> deleted file mode 100644
> index 47a4718..0000000
> --- a/net/ipv4/netfilter/nf_nat_sip.c
> +++ /dev/null
> @@ -1,580 +0,0 @@
> -/* SIP extension for NAT alteration.
> - *
> - * (C) 2005 by Christian Hentschel <chentschel@arnet.com.ar>
> - * based on RR's ip_nat_ftp.c and other modules.
> - * (C) 2007 United Security Providers
> - * (C) 2007, 2008 Patrick McHardy <kaber@trash.net>
> - *
> - * 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.
> - */
> -
> -#include <linux/module.h>
> -#include <linux/skbuff.h>
> -#include <linux/ip.h>
> -#include <net/ip.h>
> -#include <linux/udp.h>
> -#include <linux/tcp.h>
> -
> -#include <net/netfilter/nf_nat.h>
> -#include <net/netfilter/nf_nat_helper.h>
> -#include <net/netfilter/nf_conntrack_helper.h>
> -#include <net/netfilter/nf_conntrack_expect.h>
> -#include <linux/netfilter/nf_conntrack_sip.h>
> -
> -MODULE_LICENSE("GPL");
> -MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
> -MODULE_DESCRIPTION("SIP NAT helper");
> -MODULE_ALIAS("ip_nat_sip");
> -
> -
> -static unsigned int mangle_packet(struct sk_buff *skb, unsigned int protoff,
> -				  unsigned int dataoff,
> -				  const char **dptr, unsigned int *datalen,
> -				  unsigned int matchoff, unsigned int matchlen,
> -				  const char *buffer, unsigned int buflen)
> -{
> -	enum ip_conntrack_info ctinfo;
> -	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> -	struct tcphdr *th;
> -	unsigned int baseoff;
> -
> -	if (nf_ct_protonum(ct) == IPPROTO_TCP) {
> -		th = (struct tcphdr *)(skb->data + ip_hdrlen(skb));
> -		baseoff = ip_hdrlen(skb) + th->doff * 4;
> -		matchoff += dataoff - baseoff;
> -
> -		if (!__nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
> -						protoff, matchoff, matchlen,
> -						buffer, buflen, false))
> -			return 0;
> -	} else {
> -		baseoff = ip_hdrlen(skb) + sizeof(struct udphdr);
> -		matchoff += dataoff - baseoff;
> -
> -		if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo,
> -					      protoff, matchoff, matchlen,
> -					      buffer, buflen))
> -			return 0;
> -	}
> -
> -	/* Reload data pointer and adjust datalen value */
> -	*dptr = skb->data + dataoff;
> -	*datalen += buflen - matchlen;
> -	return 1;
> -}
> -
> -static int map_addr(struct sk_buff *skb, unsigned int protoff,
> -		    unsigned int dataoff,
> -		    const char **dptr, unsigned int *datalen,
> -		    unsigned int matchoff, unsigned int matchlen,
> -		    union nf_inet_addr *addr, __be16 port)
> -{
> -	enum ip_conntrack_info ctinfo;
> -	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> -	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
> -	char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
> -	unsigned int buflen;
> -	__be32 newaddr;
> -	__be16 newport;
> -
> -	if (ct->tuplehash[dir].tuple.src.u3.ip == addr->ip &&
> -	    ct->tuplehash[dir].tuple.src.u.udp.port == port) {
> -		newaddr = ct->tuplehash[!dir].tuple.dst.u3.ip;
> -		newport = ct->tuplehash[!dir].tuple.dst.u.udp.port;
> -	} else if (ct->tuplehash[dir].tuple.dst.u3.ip == addr->ip &&
> -		   ct->tuplehash[dir].tuple.dst.u.udp.port == port) {
> -		newaddr = ct->tuplehash[!dir].tuple.src.u3.ip;
> -		newport = ct->tuplehash[!dir].tuple.src.u.udp.port;
> -	} else
> -		return 1;
> -
> -	if (newaddr == addr->ip && newport == port)
> -		return 1;
> -
> -	buflen = sprintf(buffer, "%pI4:%u", &newaddr, ntohs(newport));
> -
> -	return mangle_packet(skb, protoff, dataoff, dptr, datalen,
> -			     matchoff, matchlen, buffer, buflen);
> -}
> -
> -static int map_sip_addr(struct sk_buff *skb, unsigned int protoff,
> -			unsigned int dataoff,
> -			const char **dptr, unsigned int *datalen,
> -			enum sip_header_types type)
> -{
> -	enum ip_conntrack_info ctinfo;
> -	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> -	unsigned int matchlen, matchoff;
> -	union nf_inet_addr addr;
> -	__be16 port;
> -
> -	if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, type, NULL,
> -				    &matchoff, &matchlen, &addr, &port) <= 0)
> -		return 1;
> -	return map_addr(skb, protoff, dataoff, dptr, datalen,
> -			matchoff, matchlen, &addr, port);
> -}
> -
> -static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int protoff,
> -			       unsigned int dataoff,
> -			       const char **dptr, unsigned int *datalen)
> -{
> -	enum ip_conntrack_info ctinfo;
> -	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> -	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
> -	unsigned int coff, matchoff, matchlen;
> -	enum sip_header_types hdr;
> -	union nf_inet_addr addr;
> -	__be16 port;
> -	int request, in_header;
> -
> -	/* Basic rules: requests and responses. */
> -	if (strnicmp(*dptr, "SIP/2.0", strlen("SIP/2.0")) != 0) {
> -		if (ct_sip_parse_request(ct, *dptr, *datalen,
> -					 &matchoff, &matchlen,
> -					 &addr, &port) > 0 &&
> -		    !map_addr(skb, protoff, dataoff, dptr, datalen,
> -			      matchoff, matchlen, &addr, port))
> -			return NF_DROP;
> -		request = 1;
> -	} else
> -		request = 0;
> -
> -	if (nf_ct_protonum(ct) == IPPROTO_TCP)
> -		hdr = SIP_HDR_VIA_TCP;
> -	else
> -		hdr = SIP_HDR_VIA_UDP;
> -
> -	/* Translate topmost Via header and parameters */
> -	if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen,
> -				    hdr, NULL, &matchoff, &matchlen,
> -				    &addr, &port) > 0) {
> -		unsigned int olen, matchend, poff, plen, buflen, n;
> -		char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
> -
> -		/* We're only interested in headers related to this
> -		 * connection */
> -		if (request) {
> -			if (addr.ip != ct->tuplehash[dir].tuple.src.u3.ip ||
> -			    port != ct->tuplehash[dir].tuple.src.u.udp.port)
> -				goto next;
> -		} else {
> -			if (addr.ip != ct->tuplehash[dir].tuple.dst.u3.ip ||
> -			    port != ct->tuplehash[dir].tuple.dst.u.udp.port)
> -				goto next;
> -		}
> -
> -		olen = *datalen;
> -		if (!map_addr(skb, protoff, dataoff, dptr, datalen,
> -			      matchoff, matchlen, &addr, port))
> -			return NF_DROP;
> -
> -		matchend = matchoff + matchlen + *datalen - olen;
> -
> -		/* The maddr= parameter (RFC 2361) specifies where to send
> -		 * the reply. */
> -		if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen,
> -					       "maddr=", &poff, &plen,
> -					       &addr, true) > 0 &&
> -		    addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
> -		    addr.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) {
> -			buflen = sprintf(buffer, "%pI4",
> -					&ct->tuplehash[!dir].tuple.dst.u3.ip);
> -			if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
> -					   poff, plen, buffer, buflen))
> -				return NF_DROP;
> -		}
> -
> -		/* The received= parameter (RFC 2361) contains the address
> -		 * from which the server received the request. */
> -		if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen,
> -					       "received=", &poff, &plen,
> -					       &addr, false) > 0 &&
> -		    addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip &&
> -		    addr.ip != ct->tuplehash[!dir].tuple.src.u3.ip) {
> -			buflen = sprintf(buffer, "%pI4",
> -					&ct->tuplehash[!dir].tuple.src.u3.ip);
> -			if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
> -					   poff, plen, buffer, buflen))
> -				return NF_DROP;
> -		}
> -
> -		/* The rport= parameter (RFC 3581) contains the port number
> -		 * from which the server received the request. */
> -		if (ct_sip_parse_numerical_param(ct, *dptr, matchend, *datalen,
> -						 "rport=", &poff, &plen,
> -						 &n) > 0 &&
> -		    htons(n) == ct->tuplehash[dir].tuple.dst.u.udp.port &&
> -		    htons(n) != ct->tuplehash[!dir].tuple.src.u.udp.port) {
> -			__be16 p = ct->tuplehash[!dir].tuple.src.u.udp.port;
> -			buflen = sprintf(buffer, "%u", ntohs(p));
> -			if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
> -					   poff, plen, buffer, buflen))
> -				return NF_DROP;
> -		}
> -	}
> -
> -next:
> -	/* Translate Contact headers */
> -	coff = 0;
> -	in_header = 0;
> -	while (ct_sip_parse_header_uri(ct, *dptr, &coff, *datalen,
> -				       SIP_HDR_CONTACT, &in_header,
> -				       &matchoff, &matchlen,
> -				       &addr, &port) > 0) {
> -		if (!map_addr(skb, protoff, dataoff, dptr, datalen,
> -			      matchoff, matchlen,
> -			      &addr, port))
> -			return NF_DROP;
> -	}
> -
> -	if (!map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_FROM) ||
> -	    !map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_TO))
> -		return NF_DROP;
> -
> -	return NF_ACCEPT;
> -}
> -
> -static void ip_nat_sip_seq_adjust(struct sk_buff *skb, s16 off)
> -{
> -	enum ip_conntrack_info ctinfo;
> -	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> -	const struct tcphdr *th;
> -
> -	if (nf_ct_protonum(ct) != IPPROTO_TCP || off == 0)
> -		return;
> -
> -	th = (struct tcphdr *)(skb->data + ip_hdrlen(skb));
> -	nf_nat_set_seq_adjust(ct, ctinfo, th->seq, off);
> -}
> -
> -/* Handles expected signalling connections and media streams */
> -static void ip_nat_sip_expected(struct nf_conn *ct,
> -				struct nf_conntrack_expect *exp)
> -{
> -	struct nf_nat_range range;
> -
> -	/* This must be a fresh one. */
> -	BUG_ON(ct->status & IPS_NAT_DONE_MASK);
> -
> -	/* For DST manip, map port here to where it's expected. */
> -	range.flags = (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED);
> -	range.min_proto = range.max_proto = exp->saved_proto;
> -	range.min_addr = range.max_addr = exp->saved_addr;
> -	nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST);
> -
> -	/* Change src to where master sends to, but only if the connection
> -	 * actually came from the same source. */
> -	if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip ==
> -	    ct->master->tuplehash[exp->dir].tuple.src.u3.ip) {
> -		range.flags = NF_NAT_RANGE_MAP_IPS;
> -		range.min_addr = range.max_addr
> -			= ct->master->tuplehash[!exp->dir].tuple.dst.u3;
> -		nf_nat_setup_info(ct, &range, NF_NAT_MANIP_SRC);
> -	}
> -}
> -
> -static unsigned int ip_nat_sip_expect(struct sk_buff *skb, unsigned int protoff,
> -				      unsigned int dataoff,
> -				      const char **dptr, unsigned int *datalen,
> -				      struct nf_conntrack_expect *exp,
> -				      unsigned int matchoff,
> -				      unsigned int matchlen)
> -{
> -	enum ip_conntrack_info ctinfo;
> -	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> -	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
> -	__be32 newip;
> -	u_int16_t port;
> -	char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
> -	unsigned int buflen;
> -
> -	/* Connection will come from reply */
> -	if (ct->tuplehash[dir].tuple.src.u3.ip == ct->tuplehash[!dir].tuple.dst.u3.ip)
> -		newip = exp->tuple.dst.u3.ip;
> -	else
> -		newip = ct->tuplehash[!dir].tuple.dst.u3.ip;
> -
> -	/* If the signalling port matches the connection's source port in the
> -	 * original direction, try to use the destination port in the opposite
> -	 * direction. */
> -	if (exp->tuple.dst.u.udp.port ==
> -	    ct->tuplehash[dir].tuple.src.u.udp.port)
> -		port = ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port);
> -	else
> -		port = ntohs(exp->tuple.dst.u.udp.port);
> -
> -	exp->saved_addr = exp->tuple.dst.u3;
> -	exp->tuple.dst.u3.ip = newip;
> -	exp->saved_proto.udp.port = exp->tuple.dst.u.udp.port;
> -	exp->dir = !dir;
> -	exp->expectfn = ip_nat_sip_expected;
> -
> -	for (; port != 0; port++) {
> -		int ret;
> -
> -		exp->tuple.dst.u.udp.port = htons(port);
> -		ret = nf_ct_expect_related(exp);
> -		if (ret == 0)
> -			break;
> -		else if (ret != -EBUSY) {
> -			port = 0;
> -			break;
> -		}
> -	}
> -
> -	if (port == 0)
> -		return NF_DROP;
> -
> -	if (exp->tuple.dst.u3.ip != exp->saved_addr.ip ||
> -	    exp->tuple.dst.u.udp.port != exp->saved_proto.udp.port) {
> -		buflen = sprintf(buffer, "%pI4:%u", &newip, port);
> -		if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
> -				   matchoff, matchlen, buffer, buflen))
> -			goto err;
> -	}
> -	return NF_ACCEPT;
> -
> -err:
> -	nf_ct_unexpect_related(exp);
> -	return NF_DROP;
> -}
> -
> -static int mangle_content_len(struct sk_buff *skb, unsigned int protoff,
> -			      unsigned int dataoff,
> -			      const char **dptr, unsigned int *datalen)
> -{
> -	enum ip_conntrack_info ctinfo;
> -	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> -	unsigned int matchoff, matchlen;
> -	char buffer[sizeof("65536")];
> -	int buflen, c_len;
> -
> -	/* Get actual SDP length */
> -	if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen,
> -				  SDP_HDR_VERSION, SDP_HDR_UNSPEC,
> -				  &matchoff, &matchlen) <= 0)
> -		return 0;
> -	c_len = *datalen - matchoff + strlen("v=");
> -
> -	/* Now, update SDP length */
> -	if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CONTENT_LENGTH,
> -			      &matchoff, &matchlen) <= 0)
> -		return 0;
> -
> -	buflen = sprintf(buffer, "%u", c_len);
> -	return mangle_packet(skb, protoff, dataoff, dptr, datalen,
> -			     matchoff, matchlen, buffer, buflen);
> -}
> -
> -static int mangle_sdp_packet(struct sk_buff *skb, unsigned int protoff,
> -			     unsigned int dataoff,
> -			     const char **dptr, unsigned int *datalen,
> -			     unsigned int sdpoff,
> -			     enum sdp_header_types type,
> -			     enum sdp_header_types term,
> -			     char *buffer, int buflen)
> -{
> -	enum ip_conntrack_info ctinfo;
> -	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> -	unsigned int matchlen, matchoff;
> -
> -	if (ct_sip_get_sdp_header(ct, *dptr, sdpoff, *datalen, type, term,
> -				  &matchoff, &matchlen) <= 0)
> -		return -ENOENT;
> -	return mangle_packet(skb, protoff, dataoff, dptr, datalen,
> -			     matchoff, matchlen, buffer, buflen) ? 0 : -EINVAL;
> -}
> -
> -static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, unsigned int protoff,
> -				    unsigned int dataoff,
> -				    const char **dptr, unsigned int *datalen,
> -				    unsigned int sdpoff,
> -				    enum sdp_header_types type,
> -				    enum sdp_header_types term,
> -				    const union nf_inet_addr *addr)
> -{
> -	char buffer[sizeof("nnn.nnn.nnn.nnn")];
> -	unsigned int buflen;
> -
> -	buflen = sprintf(buffer, "%pI4", &addr->ip);
> -	if (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen,
> -			      sdpoff, type, term, buffer, buflen))
> -		return 0;
> -
> -	return mangle_content_len(skb, protoff, dataoff, dptr, datalen);
> -}
> -
> -static unsigned int ip_nat_sdp_port(struct sk_buff *skb, unsigned int protoff,
> -				    unsigned int dataoff,
> -				    const char **dptr, unsigned int *datalen,
> -				    unsigned int matchoff,
> -				    unsigned int matchlen,
> -				    u_int16_t port)
> -{
> -	char buffer[sizeof("nnnnn")];
> -	unsigned int buflen;
> -
> -	buflen = sprintf(buffer, "%u", port);
> -	if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
> -			   matchoff, matchlen, buffer, buflen))
> -		return 0;
> -
> -	return mangle_content_len(skb, protoff, dataoff, dptr, datalen);
> -}
> -
> -static unsigned int ip_nat_sdp_session(struct sk_buff *skb, unsigned int protoff,
> -				       unsigned int dataoff,
> -				       const char **dptr, unsigned int *datalen,
> -				       unsigned int sdpoff,
> -				       const union nf_inet_addr *addr)
> -{
> -	char buffer[sizeof("nnn.nnn.nnn.nnn")];
> -	unsigned int buflen;
> -
> -	/* Mangle session description owner and contact addresses */
> -	buflen = sprintf(buffer, "%pI4", &addr->ip);
> -	if (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen, sdpoff,
> -			       SDP_HDR_OWNER_IP4, SDP_HDR_MEDIA,
> -			       buffer, buflen))
> -		return 0;
> -
> -	switch (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen, sdpoff,
> -				  SDP_HDR_CONNECTION_IP4, SDP_HDR_MEDIA,
> -				  buffer, buflen)) {
> -	case 0:
> -	/*
> -	 * RFC 2327:
> -	 *
> -	 * Session description
> -	 *
> -	 * c=* (connection information - not required if included in all media)
> -	 */
> -	case -ENOENT:
> -		break;
> -	default:
> -		return 0;
> -	}
> -
> -	return mangle_content_len(skb, protoff, dataoff, dptr, datalen);
> -}
> -
> -/* So, this packet has hit the connection tracking matching code.
> -   Mangle it, and change the expectation to match the new version. */
> -static unsigned int ip_nat_sdp_media(struct sk_buff *skb, unsigned int protoff,
> -				     unsigned int dataoff,
> -				     const char **dptr, unsigned int *datalen,
> -				     struct nf_conntrack_expect *rtp_exp,
> -				     struct nf_conntrack_expect *rtcp_exp,
> -				     unsigned int mediaoff,
> -				     unsigned int medialen,
> -				     union nf_inet_addr *rtp_addr)
> -{
> -	enum ip_conntrack_info ctinfo;
> -	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> -	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
> -	u_int16_t port;
> -
> -	/* Connection will come from reply */
> -	if (ct->tuplehash[dir].tuple.src.u3.ip ==
> -	    ct->tuplehash[!dir].tuple.dst.u3.ip)
> -		rtp_addr->ip = rtp_exp->tuple.dst.u3.ip;
> -	else
> -		rtp_addr->ip = ct->tuplehash[!dir].tuple.dst.u3.ip;
> -
> -	rtp_exp->saved_addr = rtp_exp->tuple.dst.u3;
> -	rtp_exp->tuple.dst.u3.ip = rtp_addr->ip;
> -	rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port;
> -	rtp_exp->dir = !dir;
> -	rtp_exp->expectfn = ip_nat_sip_expected;
> -
> -	rtcp_exp->saved_addr = rtcp_exp->tuple.dst.u3;
> -	rtcp_exp->tuple.dst.u3.ip = rtp_addr->ip;
> -	rtcp_exp->saved_proto.udp.port = rtcp_exp->tuple.dst.u.udp.port;
> -	rtcp_exp->dir = !dir;
> -	rtcp_exp->expectfn = ip_nat_sip_expected;
> -
> -	/* Try to get same pair of ports: if not, try to change them. */
> -	for (port = ntohs(rtp_exp->tuple.dst.u.udp.port);
> -	     port != 0; port += 2) {
> -		int ret;
> -
> -		rtp_exp->tuple.dst.u.udp.port = htons(port);
> -		ret = nf_ct_expect_related(rtp_exp);
> -		if (ret == -EBUSY)
> -			continue;
> -		else if (ret < 0) {
> -			port = 0;
> -			break;
> -		}
> -		rtcp_exp->tuple.dst.u.udp.port = htons(port + 1);
> -		ret = nf_ct_expect_related(rtcp_exp);
> -		if (ret == 0)
> -			break;
> -		else if (ret != -EBUSY) {
> -			nf_ct_unexpect_related(rtp_exp);
> -			port = 0;
> -			break;
> -		}
> -	}
> -
> -	if (port == 0)
> -		goto err1;
> -
> -	/* Update media port. */
> -	if (rtp_exp->tuple.dst.u.udp.port != rtp_exp->saved_proto.udp.port &&
> -	    !ip_nat_sdp_port(skb, protoff, dataoff, dptr, datalen,
> -			     mediaoff, medialen, port))
> -		goto err2;
> -
> -	return NF_ACCEPT;
> -
> -err2:
> -	nf_ct_unexpect_related(rtp_exp);
> -	nf_ct_unexpect_related(rtcp_exp);
> -err1:
> -	return NF_DROP;
> -}
> -
> -static struct nf_ct_helper_expectfn sip_nat = {
> -        .name           = "sip",
> -        .expectfn       = ip_nat_sip_expected,
> -};
> -
> -static void __exit nf_nat_sip_fini(void)
> -{
> -	RCU_INIT_POINTER(nf_nat_sip_hook, NULL);
> -	RCU_INIT_POINTER(nf_nat_sip_seq_adjust_hook, NULL);
> -	RCU_INIT_POINTER(nf_nat_sip_expect_hook, NULL);
> -	RCU_INIT_POINTER(nf_nat_sdp_addr_hook, NULL);
> -	RCU_INIT_POINTER(nf_nat_sdp_port_hook, NULL);
> -	RCU_INIT_POINTER(nf_nat_sdp_session_hook, NULL);
> -	RCU_INIT_POINTER(nf_nat_sdp_media_hook, NULL);
> -	nf_ct_helper_expectfn_unregister(&sip_nat);
> -	synchronize_rcu();
> -}
> -
> -static int __init nf_nat_sip_init(void)
> -{
> -	BUG_ON(nf_nat_sip_hook != NULL);
> -	BUG_ON(nf_nat_sip_seq_adjust_hook != NULL);
> -	BUG_ON(nf_nat_sip_expect_hook != NULL);
> -	BUG_ON(nf_nat_sdp_addr_hook != NULL);
> -	BUG_ON(nf_nat_sdp_port_hook != NULL);
> -	BUG_ON(nf_nat_sdp_session_hook != NULL);
> -	BUG_ON(nf_nat_sdp_media_hook != NULL);
> -	RCU_INIT_POINTER(nf_nat_sip_hook, ip_nat_sip);
> -	RCU_INIT_POINTER(nf_nat_sip_seq_adjust_hook, ip_nat_sip_seq_adjust);
> -	RCU_INIT_POINTER(nf_nat_sip_expect_hook, ip_nat_sip_expect);
> -	RCU_INIT_POINTER(nf_nat_sdp_addr_hook, ip_nat_sdp_addr);
> -	RCU_INIT_POINTER(nf_nat_sdp_port_hook, ip_nat_sdp_port);
> -	RCU_INIT_POINTER(nf_nat_sdp_session_hook, ip_nat_sdp_session);
> -	RCU_INIT_POINTER(nf_nat_sdp_media_hook, ip_nat_sdp_media);
> -	nf_ct_helper_expectfn_register(&sip_nat);
> -	return 0;
> -}
> -
> -module_init(nf_nat_sip_init);
> -module_exit(nf_nat_sip_fini);
> diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
> index 2eee9f1..bf3e464 100644
> --- a/net/netfilter/Kconfig
> +++ b/net/netfilter/Kconfig
> @@ -390,6 +390,11 @@ config NF_NAT_FTP
>  	depends on NF_CONNTRACK && NF_NAT
>  	default NF_NAT && NF_CONNTRACK_FTP
>  
> +config NF_NAT_SIP
> +	tristate
> +	depends on NF_CONNTRACK && NF_NAT
> +	default NF_NAT && NF_CONNTRACK_SIP
> +
>  endif # NF_CONNTRACK
>  
>  # transparent proxy support
> diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
> index 7d6e1ea..7d6d1a0 100644
> --- a/net/netfilter/Makefile
> +++ b/net/netfilter/Makefile
> @@ -57,6 +57,7 @@ obj-$(CONFIG_NF_NAT_PROTO_SCTP) += nf_nat_proto_sctp.o
>  # NAT helpers
>  obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
>  obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
> +obj-$(CONFIG_NF_NAT_SIP) += nf_nat_sip.o
>  
>  # transparent proxy support
>  obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o
> diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
> index d517490..df8f4f2 100644
> --- a/net/netfilter/nf_conntrack_sip.c
> +++ b/net/netfilter/nf_conntrack_sip.c
> @@ -57,7 +57,8 @@ unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb, unsigned int protoff,
>  				unsigned int *datalen) __read_mostly;
>  EXPORT_SYMBOL_GPL(nf_nat_sip_hook);
>  
> -void (*nf_nat_sip_seq_adjust_hook)(struct sk_buff *skb, s16 off) __read_mostly;
> +void (*nf_nat_sip_seq_adjust_hook)(struct sk_buff *skb, unsigned int protoff,
> +				   s16 off) __read_mostly;
>  EXPORT_SYMBOL_GPL(nf_nat_sip_seq_adjust_hook);
>  
>  unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb,
> @@ -742,13 +743,18 @@ static int sdp_addr_len(const struct nf_conn *ct, const char *dptr,
>   * be tolerant and also accept records terminated with a single newline
>   * character". We handle both cases.
>   */
> -static const struct sip_header ct_sdp_hdrs[] = {
> -	[SDP_HDR_VERSION]		= SDP_HDR("v=", NULL, digits_len),
> -	[SDP_HDR_OWNER_IP4]		= SDP_HDR("o=", "IN IP4 ", sdp_addr_len),
> -	[SDP_HDR_CONNECTION_IP4]	= SDP_HDR("c=", "IN IP4 ", sdp_addr_len),
> -	[SDP_HDR_OWNER_IP6]		= SDP_HDR("o=", "IN IP6 ", sdp_addr_len),
> -	[SDP_HDR_CONNECTION_IP6]	= SDP_HDR("c=", "IN IP6 ", sdp_addr_len),
> -	[SDP_HDR_MEDIA]			= SDP_HDR("m=", NULL, media_len),
> +static const struct sip_header ct_sdp_hdrs_v4[] = {
> +	[SDP_HDR_VERSION]	= SDP_HDR("v=", NULL, digits_len),
> +	[SDP_HDR_OWNER]		= SDP_HDR("o=", "IN IP4 ", sdp_addr_len),
> +	[SDP_HDR_CONNECTION]	= SDP_HDR("c=", "IN IP4 ", sdp_addr_len),
> +	[SDP_HDR_MEDIA]		= SDP_HDR("m=", NULL, media_len),
> +};
> +
> +static const struct sip_header ct_sdp_hdrs_v6[] = {
> +	[SDP_HDR_VERSION]	= SDP_HDR("v=", NULL, digits_len),
> +	[SDP_HDR_OWNER]		= SDP_HDR("o=", "IN IP6 ", sdp_addr_len),
> +	[SDP_HDR_CONNECTION]	= SDP_HDR("c=", "IN IP6 ", sdp_addr_len),
> +	[SDP_HDR_MEDIA]		= SDP_HDR("m=", NULL, media_len),
>  };
>  
>  /* Linear string search within SDP header values */
> @@ -774,11 +780,14 @@ int ct_sip_get_sdp_header(const struct nf_conn *ct, const char *dptr,
>  			  enum sdp_header_types term,
>  			  unsigned int *matchoff, unsigned int *matchlen)
>  {
> -	const struct sip_header *hdr = &ct_sdp_hdrs[type];
> -	const struct sip_header *thdr = &ct_sdp_hdrs[term];
> +	const struct sip_header *hdrs, *hdr, *thdr;
>  	const char *start = dptr, *limit = dptr + datalen;
>  	int shift = 0;
>  
> +	hdrs = nf_ct_l3num(ct) == NFPROTO_IPV4 ? ct_sdp_hdrs_v4 : ct_sdp_hdrs_v6;
> +	hdr = &hdrs[type];
> +	thdr = &hdrs[term];
> +
>  	for (dptr += dataoff; dptr < limit; dptr++) {
>  		/* Find beginning of line */
>  		if (*dptr != '\r' && *dptr != '\n')
> @@ -945,12 +954,12 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,
>  		    exp->class != class)
>  			break;
>  #ifdef CONFIG_NF_NAT_NEEDED
> -		if (exp->tuple.src.l3num == AF_INET && !direct_rtp &&
> -		    (exp->saved_addr.ip != exp->tuple.dst.u3.ip ||
> +		if (!direct_rtp &&
> +		    (!nf_inet_addr_cmp(&exp->saved_addr, &exp->tuple.dst.u3) ||
>  		     exp->saved_proto.udp.port != exp->tuple.dst.u.udp.port) &&
>  		    ct->status & IPS_NAT_MASK) {
> -			daddr->ip		= exp->saved_addr.ip;
> -			tuple.dst.u3.ip		= exp->saved_addr.ip;
> +			*daddr			= exp->saved_addr;
> +			tuple.dst.u3		= exp->saved_addr;
>  			tuple.dst.u.udp.port	= exp->saved_proto.udp.port;
>  			direct_rtp = 1;
>  		} else
> @@ -987,8 +996,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,
>  			  IPPROTO_UDP, NULL, &rtcp_port);
>  
>  	nf_nat_sdp_media = rcu_dereference(nf_nat_sdp_media_hook);
> -	if (nf_nat_sdp_media && nf_ct_l3num(ct) == NFPROTO_IPV4 &&
> -	    ct->status & IPS_NAT_MASK && !direct_rtp)
> +	if (nf_nat_sdp_media && ct->status & IPS_NAT_MASK && !direct_rtp)
>  		ret = nf_nat_sdp_media(skb, protoff, dataoff, dptr, datalen,
>  				       rtp_exp, rtcp_exp,
>  				       mediaoff, medialen, daddr);
> @@ -1044,15 +1052,12 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff,
>  	unsigned int i;
>  	union nf_inet_addr caddr, maddr, rtp_addr;
>  	unsigned int port;
> -	enum sdp_header_types c_hdr;
>  	const struct sdp_media_type *t;
>  	int ret = NF_ACCEPT;
>  	typeof(nf_nat_sdp_addr_hook) nf_nat_sdp_addr;
>  	typeof(nf_nat_sdp_session_hook) nf_nat_sdp_session;
>  
>  	nf_nat_sdp_addr = rcu_dereference(nf_nat_sdp_addr_hook);
> -	c_hdr = nf_ct_l3num(ct) == AF_INET ? SDP_HDR_CONNECTION_IP4 :
> -					     SDP_HDR_CONNECTION_IP6;
>  
>  	/* Find beginning of session description */
>  	if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen,
> @@ -1066,7 +1071,7 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff,
>  	 * the end of the session description. */
>  	caddr_len = 0;
>  	if (ct_sip_parse_sdp_addr(ct, *dptr, sdpoff, *datalen,
> -				  c_hdr, SDP_HDR_MEDIA,
> +				  SDP_HDR_CONNECTION, SDP_HDR_MEDIA,
>  				  &matchoff, &matchlen, &caddr) > 0)
>  		caddr_len = matchlen;
>  
> @@ -1096,7 +1101,7 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff,
>  		/* The media description overrides the session description. */
>  		maddr_len = 0;
>  		if (ct_sip_parse_sdp_addr(ct, *dptr, mediaoff, *datalen,
> -					  c_hdr, SDP_HDR_MEDIA,
> +					  SDP_HDR_CONNECTION, SDP_HDR_MEDIA,
>  					  &matchoff, &matchlen, &maddr) > 0) {
>  			maddr_len = matchlen;
>  			memcpy(&rtp_addr, &maddr, sizeof(rtp_addr));
> @@ -1113,11 +1118,10 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff,
>  			return ret;
>  
>  		/* Update media connection address if present */
> -		if (maddr_len && nf_nat_sdp_addr &&
> -		    nf_ct_l3num(ct) == NFPROTO_IPV4 && ct->status & IPS_NAT_MASK) {
> +		if (maddr_len && nf_nat_sdp_addr && ct->status & IPS_NAT_MASK) {
>  			ret = nf_nat_sdp_addr(skb, protoff, dataoff,
> -					      dptr, datalen,
> -					      mediaoff, c_hdr, SDP_HDR_MEDIA,
> +					      dptr, datalen, mediaoff,
> +					      SDP_HDR_CONNECTION, SDP_HDR_MEDIA,
>  					      &rtp_addr);
>  			if (ret != NF_ACCEPT)
>  				return ret;
> @@ -1127,8 +1131,7 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff,
>  
>  	/* Update session connection and owner addresses */
>  	nf_nat_sdp_session = rcu_dereference(nf_nat_sdp_session_hook);
> -	if (nf_nat_sdp_session && nf_ct_l3num(ct) == NFPROTO_IPV4 &&
> -	    ct->status & IPS_NAT_MASK)
> +	if (nf_nat_sdp_session && ct->status & IPS_NAT_MASK)
>  		ret = nf_nat_sdp_session(skb, protoff, dataoff,
>  					 dptr, datalen, sdpoff, &rtp_addr);
>  
> @@ -1293,8 +1296,7 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff,
>  	exp->flags = NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE;
>  
>  	nf_nat_sip_expect = rcu_dereference(nf_nat_sip_expect_hook);
> -	if (nf_nat_sip_expect && nf_ct_l3num(ct) == NFPROTO_IPV4 &&
> -	    ct->status & IPS_NAT_MASK)
> +	if (nf_nat_sip_expect && ct->status & IPS_NAT_MASK)
>  		ret = nf_nat_sip_expect(skb, protoff, dataoff, dptr, datalen,
>  					exp, matchoff, matchlen);
>  	else {
> @@ -1476,8 +1478,7 @@ static int process_sip_msg(struct sk_buff *skb, struct nf_conn *ct,
>  	else
>  		ret = process_sip_response(skb, protoff, dataoff, dptr, datalen);
>  
> -	if (ret == NF_ACCEPT && nf_ct_l3num(ct) == NFPROTO_IPV4 &&
> -	    ct->status & IPS_NAT_MASK) {
> +	if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) {
>  		nf_nat_sip = rcu_dereference(nf_nat_sip_hook);
>  		if (nf_nat_sip && !nf_nat_sip(skb, protoff, dataoff,
>  					      dptr, datalen))
> @@ -1560,11 +1561,10 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
>  		datalen  = datalen + diff - msglen;
>  	}
>  
> -	if (ret == NF_ACCEPT && nf_ct_l3num(ct) == NFPROTO_IPV4 &&
> -	    ct->status & IPS_NAT_MASK) {
> +	if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) {
>  		nf_nat_sip_seq_adjust = rcu_dereference(nf_nat_sip_seq_adjust_hook);
>  		if (nf_nat_sip_seq_adjust)
> -			nf_nat_sip_seq_adjust(skb, tdiff);
> +			nf_nat_sip_seq_adjust(skb, protoff, tdiff);
>  	}
>  
>  	return ret;
> diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c
> new file mode 100644
> index 0000000..f4db3a7
> --- /dev/null
> +++ b/net/netfilter/nf_nat_sip.c
> @@ -0,0 +1,609 @@
> +/* SIP extension for NAT alteration.
> + *
> + * (C) 2005 by Christian Hentschel <chentschel@arnet.com.ar>
> + * based on RR's ip_nat_ftp.c and other modules.
> + * (C) 2007 United Security Providers
> + * (C) 2007, 2008, 2011, 2012 Patrick McHardy <kaber@trash.net>
> + *
> + * 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.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/skbuff.h>
> +#include <linux/inet.h>
> +#include <linux/udp.h>
> +#include <linux/tcp.h>
> +
> +#include <net/netfilter/nf_nat.h>
> +#include <net/netfilter/nf_nat_helper.h>
> +#include <net/netfilter/nf_conntrack_helper.h>
> +#include <net/netfilter/nf_conntrack_expect.h>
> +#include <linux/netfilter/nf_conntrack_sip.h>
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
> +MODULE_DESCRIPTION("SIP NAT helper");
> +MODULE_ALIAS("ip_nat_sip");
> +
> +
> +static unsigned int mangle_packet(struct sk_buff *skb, unsigned int protoff,
> +				  unsigned int dataoff,
> +				  const char **dptr, unsigned int *datalen,
> +				  unsigned int matchoff, unsigned int matchlen,
> +				  const char *buffer, unsigned int buflen)
> +{
> +	enum ip_conntrack_info ctinfo;
> +	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> +	struct tcphdr *th;
> +	unsigned int baseoff;
> +
> +	if (nf_ct_protonum(ct) == IPPROTO_TCP) {
> +		th = (struct tcphdr *)(skb->data + protoff);
> +		baseoff = protoff + th->doff * 4;
> +		matchoff += dataoff - baseoff;
> +
> +		if (!__nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
> +						protoff, matchoff, matchlen,
> +						buffer, buflen, false))
> +			return 0;
> +	} else {
> +		baseoff = protoff + sizeof(struct udphdr);
> +		matchoff += dataoff - baseoff;
> +
> +		if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo,
> +					      protoff, matchoff, matchlen,
> +					      buffer, buflen))
> +			return 0;
> +	}
> +
> +	/* Reload data pointer and adjust datalen value */
> +	*dptr = skb->data + dataoff;
> +	*datalen += buflen - matchlen;
> +	return 1;
> +}
> +
> +static int sip_sprintf_addr(const struct nf_conn *ct, char *buffer,
> +			    const union nf_inet_addr *addr, bool delim)
> +{
> +	if (nf_ct_l3num(ct) == NFPROTO_IPV4)
> +		return sprintf(buffer, "%pI4", &addr->ip);
> +	else {
> +		if (delim)
> +			return sprintf(buffer, "[%pI6c]", &addr->ip6);
> +		else
> +			return sprintf(buffer, "%pI6c", &addr->ip6);
> +	}
> +}
> +
> +static int sip_sprintf_addr_port(const struct nf_conn *ct, char *buffer,
> +				 const union nf_inet_addr *addr, u16 port)
> +{
> +	if (nf_ct_l3num(ct) == NFPROTO_IPV4)
> +		return sprintf(buffer, "%pI4:%u", &addr->ip, port);
> +	else
> +		return sprintf(buffer, "[%pI6c]:%u", &addr->ip6, port);
> +}
> +
> +static int map_addr(struct sk_buff *skb, unsigned int protoff,
> +		    unsigned int dataoff,
> +		    const char **dptr, unsigned int *datalen,
> +		    unsigned int matchoff, unsigned int matchlen,
> +		    union nf_inet_addr *addr, __be16 port)
> +{
> +	enum ip_conntrack_info ctinfo;
> +	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> +	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
> +	char buffer[INET6_ADDRSTRLEN + sizeof("[]:nnnnn")];
> +	unsigned int buflen;
> +	union nf_inet_addr newaddr;
> +	__be16 newport;
> +
> +	if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, addr) &&
> +	    ct->tuplehash[dir].tuple.src.u.udp.port == port) {
> +		newaddr = ct->tuplehash[!dir].tuple.dst.u3;
> +		newport = ct->tuplehash[!dir].tuple.dst.u.udp.port;
> +	} else if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3, addr) &&
> +		   ct->tuplehash[dir].tuple.dst.u.udp.port == port) {
> +		newaddr = ct->tuplehash[!dir].tuple.src.u3;
> +		newport = ct->tuplehash[!dir].tuple.src.u.udp.port;
> +	} else
> +		return 1;
> +
> +	if (nf_inet_addr_cmp(&newaddr, addr) && newport == port)
> +		return 1;
> +
> +	buflen = sip_sprintf_addr_port(ct, buffer, &newaddr, ntohs(newport));
> +	return mangle_packet(skb, protoff, dataoff, dptr, datalen,
> +			     matchoff, matchlen, buffer, buflen);
> +}
> +
> +static int map_sip_addr(struct sk_buff *skb, unsigned int protoff,
> +			unsigned int dataoff,
> +			const char **dptr, unsigned int *datalen,
> +			enum sip_header_types type)
> +{
> +	enum ip_conntrack_info ctinfo;
> +	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> +	unsigned int matchlen, matchoff;
> +	union nf_inet_addr addr;
> +	__be16 port;
> +
> +	if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, type, NULL,
> +				    &matchoff, &matchlen, &addr, &port) <= 0)
> +		return 1;
> +	return map_addr(skb, protoff, dataoff, dptr, datalen,
> +			matchoff, matchlen, &addr, port);
> +}
> +
> +static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff,
> +			       unsigned int dataoff,
> +			       const char **dptr, unsigned int *datalen)
> +{
> +	enum ip_conntrack_info ctinfo;
> +	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> +	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
> +	unsigned int coff, matchoff, matchlen;
> +	enum sip_header_types hdr;
> +	union nf_inet_addr addr;
> +	__be16 port;
> +	int request, in_header;
> +
> +	/* Basic rules: requests and responses. */
> +	if (strnicmp(*dptr, "SIP/2.0", strlen("SIP/2.0")) != 0) {
> +		if (ct_sip_parse_request(ct, *dptr, *datalen,
> +					 &matchoff, &matchlen,
> +					 &addr, &port) > 0 &&
> +		    !map_addr(skb, protoff, dataoff, dptr, datalen,
> +			      matchoff, matchlen, &addr, port))
> +			return NF_DROP;
> +		request = 1;
> +	} else
> +		request = 0;
> +
> +	if (nf_ct_protonum(ct) == IPPROTO_TCP)
> +		hdr = SIP_HDR_VIA_TCP;
> +	else
> +		hdr = SIP_HDR_VIA_UDP;
> +
> +	/* Translate topmost Via header and parameters */
> +	if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen,
> +				    hdr, NULL, &matchoff, &matchlen,
> +				    &addr, &port) > 0) {
> +		unsigned int olen, matchend, poff, plen, buflen, n;
> +		char buffer[INET6_ADDRSTRLEN + sizeof("[]:nnnnn")];
> +
> +		/* We're only interested in headers related to this
> +		 * connection */
> +		if (request) {
> +			if (!nf_inet_addr_cmp(&addr,
> +					&ct->tuplehash[dir].tuple.src.u3) ||
> +			    port != ct->tuplehash[dir].tuple.src.u.udp.port)
> +				goto next;
> +		} else {
> +			if (!nf_inet_addr_cmp(&addr,
> +					&ct->tuplehash[dir].tuple.dst.u3) ||
> +			    port != ct->tuplehash[dir].tuple.dst.u.udp.port)
> +				goto next;
> +		}
> +
> +		olen = *datalen;
> +		if (!map_addr(skb, protoff, dataoff, dptr, datalen,
> +			      matchoff, matchlen, &addr, port))
> +			return NF_DROP;
> +
> +		matchend = matchoff + matchlen + *datalen - olen;
> +
> +		/* The maddr= parameter (RFC 2361) specifies where to send
> +		 * the reply. */
> +		if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen,
> +					       "maddr=", &poff, &plen,
> +					       &addr, true) > 0 &&
> +		    nf_inet_addr_cmp(&addr, &ct->tuplehash[dir].tuple.src.u3) &&
> +		    !nf_inet_addr_cmp(&addr, &ct->tuplehash[!dir].tuple.dst.u3)) {
> +			buflen = sip_sprintf_addr(ct, buffer,
> +					&ct->tuplehash[!dir].tuple.dst.u3,
> +					true);
> +			if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
> +					   poff, plen, buffer, buflen))
> +				return NF_DROP;
> +		}
> +
> +		/* The received= parameter (RFC 2361) contains the address
> +		 * from which the server received the request. */
> +		if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen,
> +					       "received=", &poff, &plen,
> +					       &addr, false) > 0 &&
> +		    nf_inet_addr_cmp(&addr, &ct->tuplehash[dir].tuple.dst.u3) &&
> +		    !nf_inet_addr_cmp(&addr, &ct->tuplehash[!dir].tuple.src.u3)) {
> +			buflen = sip_sprintf_addr(ct, buffer,
> +					&ct->tuplehash[!dir].tuple.src.u3,
> +					false);
> +			if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
> +					   poff, plen, buffer, buflen))
> +				return NF_DROP;
> +		}
> +
> +		/* The rport= parameter (RFC 3581) contains the port number
> +		 * from which the server received the request. */
> +		if (ct_sip_parse_numerical_param(ct, *dptr, matchend, *datalen,
> +						 "rport=", &poff, &plen,
> +						 &n) > 0 &&
> +		    htons(n) == ct->tuplehash[dir].tuple.dst.u.udp.port &&
> +		    htons(n) != ct->tuplehash[!dir].tuple.src.u.udp.port) {
> +			__be16 p = ct->tuplehash[!dir].tuple.src.u.udp.port;
> +			buflen = sprintf(buffer, "%u", ntohs(p));
> +			if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
> +					   poff, plen, buffer, buflen))
> +				return NF_DROP;
> +		}
> +	}
> +
> +next:
> +	/* Translate Contact headers */
> +	coff = 0;
> +	in_header = 0;
> +	while (ct_sip_parse_header_uri(ct, *dptr, &coff, *datalen,
> +				       SIP_HDR_CONTACT, &in_header,
> +				       &matchoff, &matchlen,
> +				       &addr, &port) > 0) {
> +		if (!map_addr(skb, protoff, dataoff, dptr, datalen,
> +			      matchoff, matchlen,
> +			      &addr, port))
> +			return NF_DROP;
> +	}
> +
> +	if (!map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_FROM) ||
> +	    !map_sip_addr(skb, protoff, dataoff, dptr, datalen, SIP_HDR_TO))
> +		return NF_DROP;
> +
> +	return NF_ACCEPT;
> +}
> +
> +static void nf_nat_sip_seq_adjust(struct sk_buff *skb, unsigned int protoff,
> +				  s16 off)
> +{
> +	enum ip_conntrack_info ctinfo;
> +	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> +	const struct tcphdr *th;
> +
> +	if (nf_ct_protonum(ct) != IPPROTO_TCP || off == 0)
> +		return;
> +
> +	th = (struct tcphdr *)(skb->data + protoff);
> +	nf_nat_set_seq_adjust(ct, ctinfo, th->seq, off);
> +}
> +
> +/* Handles expected signalling connections and media streams */
> +static void nf_nat_sip_expected(struct nf_conn *ct,
> +				struct nf_conntrack_expect *exp)
> +{
> +	struct nf_nat_range range;
> +
> +	/* This must be a fresh one. */
> +	BUG_ON(ct->status & IPS_NAT_DONE_MASK);
> +
> +	/* For DST manip, map port here to where it's expected. */
> +	range.flags = (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED);
> +	range.min_proto = range.max_proto = exp->saved_proto;
> +	range.min_addr = range.max_addr = exp->saved_addr;
> +	nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST);
> +
> +	/* Change src to where master sends to, but only if the connection
> +	 * actually came from the same source. */
> +	if (nf_inet_addr_cmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3,
> +			     &ct->master->tuplehash[exp->dir].tuple.src.u3)) {
> +		range.flags = NF_NAT_RANGE_MAP_IPS;
> +		range.min_addr = range.max_addr
> +			= ct->master->tuplehash[!exp->dir].tuple.dst.u3;
> +		nf_nat_setup_info(ct, &range, NF_NAT_MANIP_SRC);
> +	}
> +}
> +
> +static unsigned int nf_nat_sip_expect(struct sk_buff *skb, unsigned int protoff,
> +				      unsigned int dataoff,
> +				      const char **dptr, unsigned int *datalen,
> +				      struct nf_conntrack_expect *exp,
> +				      unsigned int matchoff,
> +				      unsigned int matchlen)
> +{
> +	enum ip_conntrack_info ctinfo;
> +	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> +	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
> +	union nf_inet_addr newaddr;
> +	u_int16_t port;
> +	char buffer[INET6_ADDRSTRLEN + sizeof("[]:nnnnn")];
> +	unsigned int buflen;
> +
> +	/* Connection will come from reply */
> +	if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3,
> +			     &ct->tuplehash[!dir].tuple.dst.u3))
> +		newaddr = exp->tuple.dst.u3;
> +	else
> +		newaddr = ct->tuplehash[!dir].tuple.dst.u3;
> +
> +	/* If the signalling port matches the connection's source port in the
> +	 * original direction, try to use the destination port in the opposite
> +	 * direction. */
> +	if (exp->tuple.dst.u.udp.port ==
> +	    ct->tuplehash[dir].tuple.src.u.udp.port)
> +		port = ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port);
> +	else
> +		port = ntohs(exp->tuple.dst.u.udp.port);
> +
> +	exp->saved_addr = exp->tuple.dst.u3;
> +	exp->tuple.dst.u3 = newaddr;
> +	exp->saved_proto.udp.port = exp->tuple.dst.u.udp.port;
> +	exp->dir = !dir;
> +	exp->expectfn = nf_nat_sip_expected;
> +
> +	for (; port != 0; port++) {
> +		int ret;
> +
> +		exp->tuple.dst.u.udp.port = htons(port);
> +		ret = nf_ct_expect_related(exp);
> +		if (ret == 0)
> +			break;
> +		else if (ret != -EBUSY) {
> +			port = 0;
> +			break;
> +		}
> +	}
> +
> +	if (port == 0)
> +		return NF_DROP;
> +
> +	if (!nf_inet_addr_cmp(&exp->tuple.dst.u3, &exp->saved_addr) ||
> +	    exp->tuple.dst.u.udp.port != exp->saved_proto.udp.port) {
> +		buflen = sip_sprintf_addr_port(ct, buffer, &newaddr, port);
> +		if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
> +				   matchoff, matchlen, buffer, buflen))
> +			goto err;
> +	}
> +	return NF_ACCEPT;
> +
> +err:
> +	nf_ct_unexpect_related(exp);
> +	return NF_DROP;
> +}
> +
> +static int mangle_content_len(struct sk_buff *skb, unsigned int protoff,
> +			      unsigned int dataoff,
> +			      const char **dptr, unsigned int *datalen)
> +{
> +	enum ip_conntrack_info ctinfo;
> +	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> +	unsigned int matchoff, matchlen;
> +	char buffer[sizeof("65536")];
> +	int buflen, c_len;
> +
> +	/* Get actual SDP length */
> +	if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen,
> +				  SDP_HDR_VERSION, SDP_HDR_UNSPEC,
> +				  &matchoff, &matchlen) <= 0)
> +		return 0;
> +	c_len = *datalen - matchoff + strlen("v=");
> +
> +	/* Now, update SDP length */
> +	if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CONTENT_LENGTH,
> +			      &matchoff, &matchlen) <= 0)
> +		return 0;
> +
> +	buflen = sprintf(buffer, "%u", c_len);
> +	return mangle_packet(skb, protoff, dataoff, dptr, datalen,
> +			     matchoff, matchlen, buffer, buflen);
> +}
> +
> +static int mangle_sdp_packet(struct sk_buff *skb, unsigned int protoff,
> +			     unsigned int dataoff,
> +			     const char **dptr, unsigned int *datalen,
> +			     unsigned int sdpoff,
> +			     enum sdp_header_types type,
> +			     enum sdp_header_types term,
> +			     char *buffer, int buflen)
> +{
> +	enum ip_conntrack_info ctinfo;
> +	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> +	unsigned int matchlen, matchoff;
> +
> +	if (ct_sip_get_sdp_header(ct, *dptr, sdpoff, *datalen, type, term,
> +				  &matchoff, &matchlen) <= 0)
> +		return -ENOENT;
> +	return mangle_packet(skb, protoff, dataoff, dptr, datalen,
> +			     matchoff, matchlen, buffer, buflen) ? 0 : -EINVAL;
> +}
> +
> +static unsigned int nf_nat_sdp_addr(struct sk_buff *skb, unsigned int protoff,
> +				    unsigned int dataoff,
> +				    const char **dptr, unsigned int *datalen,
> +				    unsigned int sdpoff,
> +				    enum sdp_header_types type,
> +				    enum sdp_header_types term,
> +				    const union nf_inet_addr *addr)
> +{
> +	enum ip_conntrack_info ctinfo;
> +	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> +	char buffer[INET6_ADDRSTRLEN];
> +	unsigned int buflen;
> +
> +	buflen = sip_sprintf_addr(ct, buffer, addr, false);
> +	if (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen,
> +			      sdpoff, type, term, buffer, buflen))
> +		return 0;
> +
> +	return mangle_content_len(skb, protoff, dataoff, dptr, datalen);
> +}
> +
> +static unsigned int nf_nat_sdp_port(struct sk_buff *skb, unsigned int protoff,
> +				    unsigned int dataoff,
> +				    const char **dptr, unsigned int *datalen,
> +				    unsigned int matchoff,
> +				    unsigned int matchlen,
> +				    u_int16_t port)
> +{
> +	char buffer[sizeof("nnnnn")];
> +	unsigned int buflen;
> +
> +	buflen = sprintf(buffer, "%u", port);
> +	if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
> +			   matchoff, matchlen, buffer, buflen))
> +		return 0;
> +
> +	return mangle_content_len(skb, protoff, dataoff, dptr, datalen);
> +}
> +
> +static unsigned int nf_nat_sdp_session(struct sk_buff *skb, unsigned int protoff,
> +				       unsigned int dataoff,
> +				       const char **dptr, unsigned int *datalen,
> +				       unsigned int sdpoff,
> +				       const union nf_inet_addr *addr)
> +{
> +	enum ip_conntrack_info ctinfo;
> +	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> +	char buffer[INET6_ADDRSTRLEN];
> +	unsigned int buflen;
> +
> +	/* Mangle session description owner and contact addresses */
> +	buflen = sip_sprintf_addr(ct, buffer, addr, false);
> +	if (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen, sdpoff,
> +			      SDP_HDR_OWNER, SDP_HDR_MEDIA, buffer, buflen))
> +		return 0;
> +
> +	switch (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen, sdpoff,
> +				  SDP_HDR_CONNECTION, SDP_HDR_MEDIA,
> +				  buffer, buflen)) {
> +	case 0:
> +	/*
> +	 * RFC 2327:
> +	 *
> +	 * Session description
> +	 *
> +	 * c=* (connection information - not required if included in all media)
> +	 */
> +	case -ENOENT:
> +		break;
> +	default:
> +		return 0;
> +	}
> +
> +	return mangle_content_len(skb, protoff, dataoff, dptr, datalen);
> +}
> +
> +/* So, this packet has hit the connection tracking matching code.
> +   Mangle it, and change the expectation to match the new version. */
> +static unsigned int nf_nat_sdp_media(struct sk_buff *skb, unsigned int protoff,
> +				     unsigned int dataoff,
> +				     const char **dptr, unsigned int *datalen,
> +				     struct nf_conntrack_expect *rtp_exp,
> +				     struct nf_conntrack_expect *rtcp_exp,
> +				     unsigned int mediaoff,
> +				     unsigned int medialen,
> +				     union nf_inet_addr *rtp_addr)
> +{
> +	enum ip_conntrack_info ctinfo;
> +	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
> +	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
> +	u_int16_t port;
> +
> +	/* Connection will come from reply */
> +	if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3,
> +			     &ct->tuplehash[!dir].tuple.dst.u3))
> +		*rtp_addr = rtp_exp->tuple.dst.u3;
> +	else
> +		*rtp_addr = ct->tuplehash[!dir].tuple.dst.u3;
> +
> +	rtp_exp->saved_addr = rtp_exp->tuple.dst.u3;
> +	rtp_exp->tuple.dst.u3 = *rtp_addr;
> +	rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port;
> +	rtp_exp->dir = !dir;
> +	rtp_exp->expectfn = nf_nat_sip_expected;
> +
> +	rtcp_exp->saved_addr = rtcp_exp->tuple.dst.u3;
> +	rtcp_exp->tuple.dst.u3 = *rtp_addr;
> +	rtcp_exp->saved_proto.udp.port = rtcp_exp->tuple.dst.u.udp.port;
> +	rtcp_exp->dir = !dir;
> +	rtcp_exp->expectfn = nf_nat_sip_expected;
> +
> +	/* Try to get same pair of ports: if not, try to change them. */
> +	for (port = ntohs(rtp_exp->tuple.dst.u.udp.port);
> +	     port != 0; port += 2) {
> +		int ret;
> +
> +		rtp_exp->tuple.dst.u.udp.port = htons(port);
> +		ret = nf_ct_expect_related(rtp_exp);
> +		if (ret == -EBUSY)
> +			continue;
> +		else if (ret < 0) {
> +			port = 0;
> +			break;
> +		}
> +		rtcp_exp->tuple.dst.u.udp.port = htons(port + 1);
> +		ret = nf_ct_expect_related(rtcp_exp);
> +		if (ret == 0)
> +			break;
> +		else if (ret != -EBUSY) {
> +			nf_ct_unexpect_related(rtp_exp);
> +			port = 0;
> +			break;
> +		}
> +	}
> +
> +	if (port == 0)
> +		goto err1;
> +
> +	/* Update media port. */
> +	if (rtp_exp->tuple.dst.u.udp.port != rtp_exp->saved_proto.udp.port &&
> +	    !nf_nat_sdp_port(skb, protoff, dataoff, dptr, datalen,
> +			     mediaoff, medialen, port))
> +		goto err2;
> +
> +	return NF_ACCEPT;
> +
> +err2:
> +	nf_ct_unexpect_related(rtp_exp);
> +	nf_ct_unexpect_related(rtcp_exp);
> +err1:
> +	return NF_DROP;
> +}
> +
> +static struct nf_ct_helper_expectfn sip_nat = {
> +	.name		= "sip",
> +	.expectfn	= nf_nat_sip_expected,
> +};
> +
> +static void __exit nf_nat_sip_fini(void)
> +{
> +	RCU_INIT_POINTER(nf_nat_sip_hook, NULL);
> +	RCU_INIT_POINTER(nf_nat_sip_seq_adjust_hook, NULL);
> +	RCU_INIT_POINTER(nf_nat_sip_expect_hook, NULL);
> +	RCU_INIT_POINTER(nf_nat_sdp_addr_hook, NULL);
> +	RCU_INIT_POINTER(nf_nat_sdp_port_hook, NULL);
> +	RCU_INIT_POINTER(nf_nat_sdp_session_hook, NULL);
> +	RCU_INIT_POINTER(nf_nat_sdp_media_hook, NULL);
> +	nf_ct_helper_expectfn_unregister(&sip_nat);
> +	synchronize_rcu();
> +}
> +
> +static int __init nf_nat_sip_init(void)
> +{
> +	BUG_ON(nf_nat_sip_hook != NULL);
> +	BUG_ON(nf_nat_sip_seq_adjust_hook != NULL);
> +	BUG_ON(nf_nat_sip_expect_hook != NULL);
> +	BUG_ON(nf_nat_sdp_addr_hook != NULL);
> +	BUG_ON(nf_nat_sdp_port_hook != NULL);
> +	BUG_ON(nf_nat_sdp_session_hook != NULL);
> +	BUG_ON(nf_nat_sdp_media_hook != NULL);
> +	RCU_INIT_POINTER(nf_nat_sip_hook, nf_nat_sip);
> +	RCU_INIT_POINTER(nf_nat_sip_seq_adjust_hook, nf_nat_sip_seq_adjust);
> +	RCU_INIT_POINTER(nf_nat_sip_expect_hook, nf_nat_sip_expect);
> +	RCU_INIT_POINTER(nf_nat_sdp_addr_hook, nf_nat_sdp_addr);
> +	RCU_INIT_POINTER(nf_nat_sdp_port_hook, nf_nat_sdp_port);
> +	RCU_INIT_POINTER(nf_nat_sdp_session_hook, nf_nat_sdp_session);
> +	RCU_INIT_POINTER(nf_nat_sdp_media_hook, nf_nat_sdp_media);
> +	nf_ct_helper_expectfn_register(&sip_nat);
> +	return 0;
> +}
> +
> +module_init(nf_nat_sip_init);
> +module_exit(nf_nat_sip_fini);

^ permalink raw reply

* Fw: [Bug 47041]  8139cp transmit queue timeout and panic
From: Stephen Hemminger @ 2012-09-04 23:26 UTC (permalink / raw)
  To: Jason Wang, Francois Romieu; +Cc: netdev


Begin forwarded message:

Date: Tue,  4 Sep 2012 23:19:34 +0000 (UTC)
From: bugzilla-daemon@bugzilla.kernel.org
To: shemminger@linux-foundation.org
Subject: [Bug 47041] New: my laptop HP Pavilion ZT3000 became unusable cause kernel panic


https://bugzilla.kernel.org/show_bug.cgi?id=47041

           Summary: my laptop HP Pavilion ZT3000 became unusable cause
                    kernel panic
           Product: Networking
           Version: 2.5
    Kernel Version: 3.5.3
          Platform: All
        OS/Version: Linux
              Tree: Mainline
            Status: NEW
          Severity: blocking
          Priority: P1
         Component: Other
        AssignedTo: shemminger@linux-foundation.org
        ReportedBy: slacky@cheapnet.it
        Regression: Yes


Created an attachment (id=79301)
 --> (https://bugzilla.kernel.org/attachment.cgi?id=79301)
dmesg from kernel 3.5.3 before to panic

I started ArchLinux with the default 3.5.3 kernel and the 8139cp doesn't work
anymore. I got IP assigned, but the network card doesn't work anymore. Till
3.4.x it worked. I've seen a problem in the dmesg I attached.

I rebooted to start with kernel 3.0.42 and the system gone into a wonderful
kernel panic.

I see new kernel release, new kernel panic introduced. Lots of regression. What
happening to the kernel source code?

-- 

---
[  108.360033] ------------[ cut here ]------------
[  108.360060] WARNING: at net/sched/sch_generic.c:255 dev_watchdog+0x1f1/0x200()
[  108.360067] Hardware name: HP Pavilion zt3000 (DX681E#ABZ) 
[  108.360074] NETDEV WATCHDOG: eth0 (8139cp): transmit queue 0 timed out
[  108.360078] Modules linked in: sha256_generic cbc usb_storage uas xt_limit xt_tcpudp xt_length xt_state iptable_mangle iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack iptable_filter ip_tables x_tables ext4 jbd2 mbcache crc16 radeon snd_intel8x0m snd_intel8x0 firewire_ohci i2c_algo_bit snd_ac97_codec joydev drm_kms_helper ttm ipw2200 libipw firewire_core ac97_bus snd_pcm cfg80211 pcmcia drm 8139too iTCO_wdt 8139cp iTCO_vendor_support snd_page_alloc rfkill lib80211 snd_timer crc_itu_t snd yenta_socket mii pcmcia_rsrc smsc_ircc2 pcmcia_core lpc_ich intel_agp serio_raw psmouse shpchp ppdev soundcore irda crc_ccitt intel_gtt agpgart microcode pci_hotplug i2c_i801 wbsd evdev i2c_core parport_pc mmc_core pcspkr parport battery container video fuse ac button cpufreq_powersave a
 cpi_cpufreq mperf processor reiserfs aes_i586 cryptd aes_generic lrw gf128mul hid_generic usbhid hid dm_crypt dm_mod sd_mod sr_mod cdrom pata_acpi ata_generic ata_piix libata scsi_mod uhci_h
 cd ehci_hcd usbcore usb_common
[  108.360320] Pid: 0, comm: swapper/0 Not tainted 3.5.3-1-ARCH #1
[  108.360324] Call Trace:
[  108.360343]  [<c0136902>] warn_slowpath_common+0x72/0xa0
[  108.360355]  [<c04049e1>] ? dev_watchdog+0x1f1/0x200
[  108.360365]  [<c04049e1>] ? dev_watchdog+0x1f1/0x200
[  108.360376]  [<c01369d3>] warn_slowpath_fmt+0x33/0x40
[  108.360387]  [<c04049e1>] dev_watchdog+0x1f1/0x200
[  108.360402]  [<c04047f0>] ? pfifo_fast_dequeue+0xe0/0xe0
[  108.360416]  [<c0145638>] run_timer_softirq+0x108/0x320
[  108.360431]  [<c01b45dc>] ? __rcu_process_callbacks+0x2ac/0x380
[  108.360442]  [<c04047f0>] ? pfifo_fast_dequeue+0xe0/0xe0
[  108.360454]  [<c013eaef>] __do_softirq+0x7f/0x1b0
[  108.360465]  [<c013ea70>] ? ftrace_define_fields_irq_handler_entry+0x80/0x80
[  108.360471]  <IRQ>  [<c013eebe>] ? irq_exit+0x7e/0xa0
[  108.360490]  [<c04cc87b>] ? do_IRQ+0x4b/0xc0
[  108.360504]  [<c01091d8>] ? sched_clock+0x8/0x10
[  108.360516]  [<c01691d2>] ? sched_clock_local+0xb2/0x1a0
[  108.360527]  [<c04cc7b0>] ? common_interrupt+0x30/0x38
[  108.360541]  [<c016007b>] ? perf_trace_sched_pi_setprio+0xab/0xe0
[  108.360566]  [<f878fe27>] ? acpi_idle_enter_simple+0x12d/0x16e [processor]
[  108.360589]  [<f878ff39>] ? acpi_idle_enter_bm+0xd1/0x2bd [processor]
[  108.360604]  [<c03c4129>] ? menu_select+0xb9/0x420
[  108.360622]  [<c03c28a5>] ? cpuidle_enter+0x15/0x20
[  108.360633]  [<c03c2e28>] ? cpuidle_idle_call+0x88/0x2d0
[  108.360647]  [<c010aeda>] ? cpu_idle+0xaa/0x100
[  108.360659]  [<c04aa4d4>] ? rest_init+0x6c/0x78
[  108.360669]  [<c06439c1>] ? start_kernel+0x362/0x368
[  108.360680]  [<c0643494>] ? repair_env_string+0x51/0x51
[  108.360691]  [<c06432c2>] ? i386_start_kernel+0x78/0x7d
[  108.360698] ---[ end trace 10638527877ea302 ]---
[  108.360717] 8139cp 0000:02:01.0: eth0: Transmit timeout, status  c   2b    0 80ff
[  108.360793] ------------[ cut here ]------------
[  108.360803] WARNING: at kernel/softirq.c:159 local_bh_enable_ip+0x68/0xa0()
[  108.360809] Hardware name: HP Pavilion zt3000 (DX681E#ABZ) 
[  108.360813] Modules linked in: sha256_generic cbc usb_storage uas xt_limit xt_tcpudp xt_length xt_state iptable_mangle iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack iptable_filter ip_tables x_tables ext4 jbd2 mbcache crc16 radeon snd_intel8x0m snd_intel8x0 firewire_ohci i2c_algo_bit snd_ac97_codec joydev drm_kms_helper ttm ipw2200 libipw firewire_core ac97_bus snd_pcm cfg80211 pcmcia drm 8139too iTCO_wdt 8139cp iTCO_vendor_support snd_page_alloc rfkill lib80211 snd_timer crc_itu_t snd yenta_socket mii pcmcia_rsrc smsc_ircc2 pcmcia_core lpc_ich intel_agp serio_raw psmouse shpchp ppdev soundcore irda crc_ccitt intel_gtt agpgart microcode pci_hotplug i2c_i801 wbsd evdev i2c_core parport_pc mmc_core pcspkr parport battery container video fuse ac button cpufreq_powersave a
 cpi_cpufreq mperf processor reiserfs aes_i586 cryptd aes_generic lrw gf128mul hid_generic usbhid hid dm_crypt dm_mod sd_mod sr_mod cdrom pata_acpi ata_generic ata_piix libata scsi_mod uhci_h
 cd ehci_hcd usbcore usb_common
[  108.361030] Pid: 0, comm: swapper/0 Tainted: G        W    3.5.3-1-ARCH #1
[  108.361033] Call Trace:
[  108.361045]  [<c0136902>] warn_slowpath_common+0x72/0xa0
[  108.361056]  [<c013e898>] ? local_bh_enable_ip+0x68/0xa0
[  108.361066]  [<c013e898>] ? local_bh_enable_ip+0x68/0xa0
[  108.361077]  [<c0136952>] warn_slowpath_null+0x22/0x30
[  108.361088]  [<c013e898>] local_bh_enable_ip+0x68/0xa0
[  108.361099]  [<c04c5dee>] _raw_spin_unlock_bh+0x1e/0x20
[  108.361116]  [<f8498a4c>] destroy_conntrack+0x7c/0xb0 [nf_conntrack]
[  108.361129]  [<c04100de>] nf_conntrack_destroy+0x1e/0x30
[  108.361141]  [<c03e00d5>] skb_release_head_state+0xa5/0xe0
[  108.361152]  [<c03dfe80>] __kfree_skb+0x10/0x90
[  108.361162]  [<c03dff27>] consume_skb+0x27/0x90
[  108.361179]  [<f8148218>] cp_clean_rings+0xf8/0x2c0 [8139cp]
[  108.361193]  [<f81486ce>] cp_tx_timeout+0x8e/0xf0 [8139cp]
[  108.361206]  [<c04049a7>] dev_watchdog+0x1b7/0x200
[  108.361218]  [<c04047f0>] ? pfifo_fast_dequeue+0xe0/0xe0
[  108.361230]  [<c0145638>] run_timer_softirq+0x108/0x320
[  108.361242]  [<c01b45dc>] ? __rcu_process_callbacks+0x2ac/0x380
[  108.361253]  [<c04047f0>] ? pfifo_fast_dequeue+0xe0/0xe0
[  108.361264]  [<c013eaef>] __do_softirq+0x7f/0x1b0
[  108.361276]  [<c013ea70>] ? ftrace_define_fields_irq_handler_entry+0x80/0x80
[  108.361281]  <IRQ>  [<c013eebe>] ? irq_exit+0x7e/0xa0
[  108.361298]  [<c04cc87b>] ? do_IRQ+0x4b/0xc0
[  108.361309]  [<c01091d8>] ? sched_clock+0x8/0x10
[  108.361320]  [<c01691d2>] ? sched_clock_local+0xb2/0x1a0
[  108.361331]  [<c04cc7b0>] ? common_interrupt+0x30/0x38
[  108.361343]  [<c016007b>] ? perf_trace_sched_pi_setprio+0xab/0xe0
[  108.361364]  [<f878fe27>] ? acpi_idle_enter_simple+0x12d/0x16e [processor]
[  108.361386]  [<f878ff39>] ? acpi_idle_enter_bm+0xd1/0x2bd [processor]
[  108.361398]  [<c03c4129>] ? menu_select+0xb9/0x420
[  108.361416]  [<c03c28a5>] ? cpuidle_enter+0x15/0x20
[  108.361427]  [<c03c2e28>] ? cpuidle_idle_call+0x88/0x2d0
[  108.361441]  [<c010aeda>] ? cpu_idle+0xaa/0x100
[  108.361451]  [<c04aa4d4>] ? rest_init+0x6c/0x78
[  108.361462]  [<c06439c1>] ? start_kernel+0x362/0x368
[  108.361473]  [<c0643494>] ? repair_env_string+0x51/0x51
[  108.361484]  [<c06432c2>] ? i386_start_kernel+0x78/0x7d
[  108.361490] ---[ end trace 10638527877ea303 ]---
[  162.360046] 8139cp 0000:02:01.0: eth0: Transmit timeout, status  c   2b    0    0
[  246.360036] 8139cp 0000:02:01.0: eth0: Transmit timeout, status  c   2b 2020    0
[  321.032996] usb 1-1: USB disconnect, device number 3
[  331.013361] 8139cp 0000:02:01.0: eth0: Transmit timeout, status  c   2b    0    0
[  331.973376] usb 1-1: new high-speed USB device number 4 using ehci_hcd
[  332.101530] scsi3 : usb-storage 1-1:1.0
[  333.104432] scsi 3:0:0:0: Direct-Access     SanDisk  Cruzer Blade     1.10 PQ: 0 ANSI: 2
[  333.111011] sd 3:0:0:0: [sdb] 31266816 512-byte logical blocks: (16.0 GB/14.9 GiB)
[  333.112504] sd 3:0:0:0: [sdb] Write Protect is off
[  333.112517] sd 3:0:0:0: [sdb] Mode Sense: 03 00 00 00
[  333.114042] sd 3:0:0:0: [sdb] No Caching mode page present
[  333.114053] sd 3:0:0:0: [sdb] Assuming drive cache: write through
[  333.119119] sd 3:0:0:0: [sdb] No Caching mode page present
[  333.119131] sd 3:0:0:0: [sdb] Assuming drive cache: write through
[  333.122919]  sdb: sdb1
[  333.126121] sd 3:0:0:0: [sdb] No Caching mode page present
[  333.126133] sd 3:0:0:0: [sdb] Assuming drive cache: write through
[  333.126143] sd 3:0:0:0: [sdb] Attached SCSI removable disk
[  385.209116] sdb: detected capacity change from 16008609792 to 0

^ permalink raw reply

* Re: [PATCH v3 01/17] hashtable: introduce a small and naive hashtable
From: Steven Rostedt @ 2012-09-04 23:27 UTC (permalink / raw)
  To: Pedro Alves
  Cc: snitzer-H+wXaHxf7aLQT0dZR+AlfA, neilb-l3A5Bk7waGM,
	fweisbec-Re5JQEeQqe8AvxtiuMwx3w,
	Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA,
	bfields-uC3wQj2KruNg9hUCZPvPmw,
	paul.gortmaker-CWA4WttNNZF54TAoqtyWWQ,
	dm-devel-H+wXaHxf7aLQT0dZR+AlfA, agk-H+wXaHxf7aLQT0dZR+AlfA,
	aarcange-H+wXaHxf7aLQT0dZR+AlfA, rds-devel-N0ozoZBvEnrZJqsBc5GL+g,
	eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
	venkat.x.venkatsubra-QHcLZuEGTsvQT0dZR+AlfA,
	ccaulfie-H+wXaHxf7aLQT0dZR+AlfA, mingo-X9Un+BFzKDI,
	dev-yBygre7rU0TnMu66kgdUjQ, ericvh-Re5JQEeQqe8AvxtiuMwx3w,
	josh-iaAMLnmF4UmaiuxdJuQwMA, lw-BthXqXjhjHXQFUHtdCDX3A,
	Mathieu Desnoyers, Sasha Levin, axboe-tSWWG44O7X1aa/9Udqfwiw,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA, edumazet-hpIqsD4AKlfQT0dZR+AlfA,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, ejt-H+wXaHxf7aLQT0dZR+AlfA,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, Tejun Heo,
	teigland-H+wXaHxf7aLQT0dZR+AlfA,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <50468778.5000207-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

On Tue, 2012-09-04 at 23:58 +0100, Pedro Alves wrote:

> Not true.  The comma operator introduces a sequence point.  It's the comma
> that separates function parameters that doesn't guarantee ordering.

Bah! C language is almost as confusing as English.

-- Steve

^ permalink raw reply

* Re: linux-next: Tree for Sept 4 (drivers/net/phy/mdio-mux-mmioreg.c)
From: Randy Dunlap @ 2012-09-04 23:48 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: linux-next, LKML, netdev, Timur Tabi
In-Reply-To: <20120904171330.f6b0a922a754ba0f3acc123b@canb.auug.org.au>

[-- Attachment #1: Type: text/plain, Size: 332 bytes --]

On 09/04/2012 12:13 AM, Stephen Rothwell wrote:

> Hi all,
> 
> Changes since 20120824:
> 


on i386:

drivers/net/phy/mdio-mux-mmioreg.c: In function 'mdio_mux_mmioreg_probe':
drivers/net/phy/mdio-mux-mmioreg.c:83:2: error: implicit declaration of function 'of_address_to_resource'


Full randconfig file is attached.


-- 
~Randy

[-- Attachment #2: config-r7341 --]
[-- Type: text/plain, Size: 64168 bytes --]

#
# Automatically generated file; DO NOT EDIT.
# Linux/i386 3.6.0-rc4 Kernel Configuration
#
# CONFIG_64BIT is not set
CONFIG_X86_32=y
# CONFIG_X86_64 is not set
CONFIG_X86=y
CONFIG_INSTRUCTION_DECODER=y
CONFIG_OUTPUT_FORMAT="elf32-i386"
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_MMU=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_GPIO=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_HAS_CPU_RELAX=y
CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
CONFIG_ARCH_HAS_CPU_AUTOPROBE=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_ZONE_DMA32 is not set
# CONFIG_AUDIT_ARCH is not set
CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_HAVE_INTEL_TXT=y
CONFIG_X86_32_LAZY_GS=y
CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-ecx -fcall-saved-edx"
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
CONFIG_HAVE_IRQ_WORK=y
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_EXTABLE_SORT=y

#
# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_CROSS_COMPILE=""
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
# CONFIG_KERNEL_GZIP is not set
CONFIG_KERNEL_BZIP2=y
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_XZ is not set
# CONFIG_KERNEL_LZO is not set
CONFIG_DEFAULT_HOSTNAME="(none)"
# CONFIG_SWAP is not set
# CONFIG_SYSVIPC is not set
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_FHANDLE=y
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
CONFIG_HAVE_GENERIC_HARDIRQS=y

#
# IRQ subsystem
#
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_IRQ_DOMAIN=y
# CONFIG_IRQ_DOMAIN_DEBUG is not set
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_KTIME_SCALAR=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
CONFIG_GENERIC_CMOS_UPDATE=y

#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y

#
# RCU Subsystem
#
CONFIG_TINY_RCU=y
# CONFIG_PREEMPT_RCU is not set
# CONFIG_TREE_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_LOG_BUF_SHIFT=17
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
CONFIG_CHECKPOINT_RESTORE=y
# CONFIG_NAMESPACES is not set
# CONFIG_SCHED_AUTOGROUP is not set
# CONFIG_SYSFS_DEPRECATED is not set
CONFIG_RELAY=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_ANON_INODES=y
CONFIG_EXPERT=y
CONFIG_UID16=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_HOTPLUG is not set
# CONFIG_PRINTK is not set
# CONFIG_BUG is not set
CONFIG_ELF_CORE=y
# CONFIG_PCSPKR_PLATFORM is not set
CONFIG_HAVE_PCSPKR_PLATFORM=y
# CONFIG_BASE_FULL is not set
CONFIG_FUTEX=y
# CONFIG_EPOLL is not set
# CONFIG_SIGNALFD is not set
# CONFIG_TIMERFD is not set
# CONFIG_EVENTFD is not set
# CONFIG_SHMEM is not set
# CONFIG_AIO is not set
CONFIG_EMBEDDED=y
CONFIG_HAVE_PERF_EVENTS=y

#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
# CONFIG_VM_EVENT_COUNTERS is not set
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
# CONFIG_COMPAT_BRK is not set
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_OPROFILE_NMI_TIMER=y
CONFIG_JUMP_LABEL=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_OPTPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_HW_BREAKPOINT=y
CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
CONFIG_HAVE_USER_RETURN_NOTIFIER=y
CONFIG_HAVE_PERF_EVENTS_NMI=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
CONFIG_HAVE_CMPXCHG_LOCAL=y
CONFIG_HAVE_CMPXCHG_DOUBLE=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_MODULES_USE_ELF_REL=y

#
# GCOV-based kernel profiling
#
CONFIG_GCOV_KERNEL=y
CONFIG_GCOV_PROFILE_ALL=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=1
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
CONFIG_LBDAF=y
CONFIG_BLK_DEV_BSG=y
CONFIG_BLK_DEV_BSGLIB=y
# CONFIG_BLK_DEV_INTEGRITY is not set

#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y

#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_DEADLINE=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="deadline"
# CONFIG_INLINE_SPIN_TRYLOCK is not set
# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
# CONFIG_INLINE_SPIN_LOCK is not set
# CONFIG_INLINE_SPIN_LOCK_BH is not set
# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
CONFIG_UNINLINE_SPIN_UNLOCK=y
# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
# CONFIG_INLINE_READ_TRYLOCK is not set
# CONFIG_INLINE_READ_LOCK is not set
# CONFIG_INLINE_READ_LOCK_BH is not set
# CONFIG_INLINE_READ_LOCK_IRQ is not set
# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
# CONFIG_INLINE_READ_UNLOCK is not set
# CONFIG_INLINE_READ_UNLOCK_BH is not set
# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
# CONFIG_INLINE_WRITE_TRYLOCK is not set
# CONFIG_INLINE_WRITE_LOCK is not set
# CONFIG_INLINE_WRITE_LOCK_BH is not set
# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
# CONFIG_INLINE_WRITE_UNLOCK is not set
# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
# CONFIG_MUTEX_SPIN_ON_OWNER is not set
CONFIG_FREEZER=y

#
# Processor type and features
#
CONFIG_ZONE_DMA=y
# CONFIG_SMP is not set
# CONFIG_X86_EXTENDED_PLATFORM is not set
CONFIG_X86_32_IRIS=y
# CONFIG_SCHED_OMIT_FRAME_POINTER is not set
CONFIG_KVMTOOL_TEST_ENABLE=y
# CONFIG_PARAVIRT_GUEST is not set
CONFIG_NO_BOOTMEM=y
# CONFIG_MEMTEST is not set
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
CONFIG_M686=y
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MELAN is not set
# CONFIG_MGEODEGX1 is not set
# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_MVIAC7 is not set
# CONFIG_MCORE2 is not set
# CONFIG_MATOM is not set
# CONFIG_X86_GENERIC is not set
CONFIG_X86_INTERNODE_CACHE_SHIFT=5
CONFIG_X86_CMPXCHG=y
CONFIG_X86_L1_CACHE_SHIFT=5
CONFIG_X86_XADD=y
CONFIG_X86_PPRO_FENCE=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_X86_TSC=y
CONFIG_X86_CMPXCHG64=y
CONFIG_X86_CMOV=y
CONFIG_X86_MINIMUM_CPU_FAMILY=5
CONFIG_X86_DEBUGCTLMSR=y
# CONFIG_PROCESSOR_SELECT is not set
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_CYRIX_32=y
CONFIG_CPU_SUP_AMD=y
CONFIG_CPU_SUP_CENTAUR=y
CONFIG_CPU_SUP_TRANSMETA_32=y
CONFIG_CPU_SUP_UMC_32=y
CONFIG_HPET_TIMER=y
CONFIG_DMI=y
# CONFIG_IOMMU_HELPER is not set
CONFIG_NR_CPUS=1
CONFIG_IRQ_TIME_ACCOUNTING=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
CONFIG_PREEMPT_COUNT=y
# CONFIG_X86_UP_APIC is not set
# CONFIG_X86_MCE is not set
CONFIG_VM86=y
# CONFIG_TOSHIBA is not set
# CONFIG_I8K is not set
CONFIG_X86_REBOOTFIXUPS=y
CONFIG_MICROCODE=y
CONFIG_MICROCODE_INTEL=y
CONFIG_MICROCODE_AMD=y
CONFIG_MICROCODE_OLD_INTERFACE=y
# CONFIG_X86_MSR is not set
# CONFIG_X86_CPUID is not set
# CONFIG_NOHIGHMEM is not set
CONFIG_HIGHMEM4G=y
# CONFIG_HIGHMEM64G is not set
# CONFIG_VMSPLIT_3G is not set
# CONFIG_VMSPLIT_3G_OPT is not set
# CONFIG_VMSPLIT_2G is not set
CONFIG_VMSPLIT_2G_OPT=y
# CONFIG_VMSPLIT_1G is not set
CONFIG_PAGE_OFFSET=0x78000000
CONFIG_HIGHMEM=y
# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ILLEGAL_POINTER_VALUE=0
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_SPARSEMEM_STATIC=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
CONFIG_ARCH_DISCARD_MEMBLOCK=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=999999
CONFIG_COMPACTION=y
CONFIG_MIGRATION=y
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_TRANSPARENT_HUGEPAGE=y
# CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set
CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
CONFIG_CROSS_MEMORY_ATTACH=y
CONFIG_NEED_PER_CPU_KM=y
CONFIG_CLEANCACHE=y
# CONFIG_HIGHPTE is not set
# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
CONFIG_X86_RESERVE_LOW=64
# CONFIG_MATH_EMULATION is not set
CONFIG_MTRR=y
# CONFIG_MTRR_SANITIZER is not set
CONFIG_X86_PAT=y
CONFIG_ARCH_USES_PG_UNCACHED=y
CONFIG_ARCH_RANDOM=y
CONFIG_EFI=y
# CONFIG_EFI_STUB is not set
# CONFIG_SECCOMP is not set
# CONFIG_CC_STACKPROTECTOR is not set
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
CONFIG_HZ_1000=y
CONFIG_HZ=1000
CONFIG_SCHED_HRTICK=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_PHYSICAL_START=0x1000000
# CONFIG_RELOCATABLE is not set
CONFIG_PHYSICAL_ALIGN=0x1000000
CONFIG_COMPAT_VDSO=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE=""
CONFIG_CMDLINE_OVERRIDE=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y

#
# Power management and ACPI options
#
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_PM_SLEEP=y
CONFIG_PM_AUTOSLEEP=y
CONFIG_PM_WAKELOCKS=y
CONFIG_PM_WAKELOCKS_LIMIT=100
# CONFIG_PM_WAKELOCKS_GC is not set
# CONFIG_PM_RUNTIME is not set
CONFIG_PM=y
CONFIG_PM_DEBUG=y
CONFIG_PM_ADVANCED_DEBUG=y
CONFIG_PM_SLEEP_DEBUG=y
# CONFIG_PM_TRACE_RTC is not set
CONFIG_ACPI=y
CONFIG_ACPI_SLEEP=y
CONFIG_ACPI_EC_DEBUGFS=y
# CONFIG_ACPI_AC is not set
CONFIG_ACPI_BATTERY=y
CONFIG_ACPI_BUTTON=y
CONFIG_ACPI_VIDEO=y
CONFIG_ACPI_FAN=y
# CONFIG_ACPI_DOCK is not set
CONFIG_ACPI_PROCESSOR=y
# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set
CONFIG_ACPI_THERMAL=y
# CONFIG_ACPI_CUSTOM_DSDT is not set
CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
# CONFIG_ACPI_PCI_SLOT is not set
CONFIG_X86_PM_TIMER=y
CONFIG_ACPI_CONTAINER=y
# CONFIG_ACPI_SBS is not set
# CONFIG_ACPI_HED is not set
# CONFIG_ACPI_CUSTOM_METHOD is not set
# CONFIG_ACPI_BGRT is not set
# CONFIG_ACPI_APEI is not set
CONFIG_SFI=y
CONFIG_X86_APM_BOOT=y
CONFIG_APM=y
CONFIG_APM_IGNORE_USER_SUSPEND=y
CONFIG_APM_DO_ENABLE=y
CONFIG_APM_CPU_IDLE=y
CONFIG_APM_DISPLAY_BLANK=y
CONFIG_APM_ALLOW_INTS=y

#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
# CONFIG_CPU_FREQ_STAT is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y

#
# x86 CPU frequency scaling drivers
#
# CONFIG_X86_PCC_CPUFREQ is not set
# CONFIG_X86_ACPI_CPUFREQ is not set
# CONFIG_X86_POWERNOW_K6 is not set
# CONFIG_X86_POWERNOW_K7 is not set
# CONFIG_X86_POWERNOW_K8 is not set
CONFIG_X86_GX_SUSPMOD=y
CONFIG_X86_SPEEDSTEP_CENTRINO=y
CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
CONFIG_X86_SPEEDSTEP_ICH=y
CONFIG_X86_SPEEDSTEP_SMI=y
CONFIG_X86_P4_CLOCKMOD=y
# CONFIG_X86_CPUFREQ_NFORCE2 is not set
CONFIG_X86_LONGRUN=y
CONFIG_X86_LONGHAUL=y
CONFIG_X86_E_POWERSAVER=y

#
# shared options
#
CONFIG_X86_SPEEDSTEP_LIB=y
CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK=y
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_LADDER=y
CONFIG_CPU_IDLE_GOV_MENU=y
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
# CONFIG_INTEL_IDLE is not set

#
# Bus options (PCI etc.)
#
CONFIG_PCI=y
# CONFIG_PCI_GOBIOS is not set
# CONFIG_PCI_GOMMCONFIG is not set
# CONFIG_PCI_GODIRECT is not set
# CONFIG_PCI_GOOLPC is not set
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_PCI_OLPC=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_CNB20LE_QUIRK=y
CONFIG_PCIEPORTBUS=y
# CONFIG_PCIEAER is not set
# CONFIG_PCIEASPM is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_MSI=y
CONFIG_PCI_DEBUG=y
# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
# CONFIG_PCI_STUB is not set
CONFIG_PCI_ATS=y
CONFIG_PCI_IOV=y
CONFIG_PCI_PRI=y
CONFIG_PCI_PASID=y
CONFIG_PCI_LABEL=y
CONFIG_ISA_DMA_API=y
# CONFIG_ISA is not set
# CONFIG_SCx200 is not set
CONFIG_OLPC=y
# CONFIG_OLPC_XO15_SCI is not set
CONFIG_ALIX=y
CONFIG_NET5501=y
CONFIG_GEOS=y
CONFIG_AMD_NB=y
CONFIG_RAPIDIO=y
CONFIG_RAPIDIO_TSI721=y
CONFIG_RAPIDIO_DISC_TIMEOUT=30
CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS=y
# CONFIG_RAPIDIO_DMA_ENGINE is not set
# CONFIG_RAPIDIO_DEBUG is not set
CONFIG_RAPIDIO_TSI57X=y
CONFIG_RAPIDIO_CPS_XX=y
# CONFIG_RAPIDIO_TSI568 is not set
# CONFIG_RAPIDIO_CPS_GEN2 is not set
# CONFIG_RAPIDIO_TSI500 is not set

#
# Executable file formats / Emulations
#
CONFIG_BINFMT_ELF=y
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
CONFIG_HAVE_AOUT=y
CONFIG_BINFMT_AOUT=y
# CONFIG_BINFMT_MISC is not set
CONFIG_HAVE_ATOMIC_IOMAP=y
CONFIG_HAVE_TEXT_POKE_SMP=y
CONFIG_NET=y

#
# Networking options
#
# CONFIG_PACKET is not set
# CONFIG_UNIX is not set
CONFIG_XFRM=y
CONFIG_XFRM_ALGO=y
CONFIG_XFRM_USER=y
# CONFIG_XFRM_SUB_POLICY is not set
CONFIG_XFRM_MIGRATE=y
CONFIG_XFRM_IPCOMP=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
CONFIG_IP_ADVANCED_ROUTER=y
# CONFIG_IP_FIB_TRIE_STATS is not set
CONFIG_IP_MULTIPLE_TABLES=y
# CONFIG_IP_ROUTE_MULTIPATH is not set
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
# CONFIG_IP_PNP_BOOTP is not set
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
CONFIG_NET_IPGRE_DEMUX=y
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_NET_IPVTI is not set
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
CONFIG_INET_XFRM_TUNNEL=y
CONFIG_INET_TUNNEL=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
CONFIG_INET_XFRM_MODE_TUNNEL=y
# CONFIG_INET_XFRM_MODE_BEET is not set
CONFIG_INET_LRO=y
# CONFIG_INET_DIAG is not set
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
# CONFIG_IPV6 is not set
CONFIG_NETLABEL=y
# CONFIG_NETWORK_SECMARK is not set
CONFIG_NETWORK_PHY_TIMESTAMPING=y
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_NETFILTER_ADVANCED=y

#
# Core Netfilter Configuration
#
CONFIG_NETFILTER_NETLINK=y
CONFIG_NETFILTER_NETLINK_ACCT=y
CONFIG_NETFILTER_NETLINK_QUEUE=y
CONFIG_NETFILTER_NETLINK_LOG=y
# CONFIG_NF_CONNTRACK is not set
CONFIG_NETFILTER_XTABLES=y

#
# Xtables combined modules
#
CONFIG_NETFILTER_XT_MARK=y
CONFIG_NETFILTER_XT_SET=y

#
# Xtables targets
#
# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
CONFIG_NETFILTER_XT_TARGET_HMARK=y
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
# CONFIG_NETFILTER_XT_TARGET_LOG is not set
CONFIG_NETFILTER_XT_TARGET_MARK=y
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
CONFIG_NETFILTER_XT_TARGET_TEE=y
CONFIG_NETFILTER_XT_TARGET_TCPMSS=y

#
# Xtables matches
#
# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
CONFIG_NETFILTER_XT_MATCH_CPU=y
CONFIG_NETFILTER_XT_MATCH_DCCP=y
# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
CONFIG_NETFILTER_XT_MATCH_DSCP=y
CONFIG_NETFILTER_XT_MATCH_ECN=y
CONFIG_NETFILTER_XT_MATCH_ESP=y
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
CONFIG_NETFILTER_XT_MATCH_HL=y
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
CONFIG_NETFILTER_XT_MATCH_LENGTH=y
# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
CONFIG_NETFILTER_XT_MATCH_MAC=y
CONFIG_NETFILTER_XT_MATCH_MARK=y
# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
CONFIG_NETFILTER_XT_MATCH_NFACCT=y
CONFIG_NETFILTER_XT_MATCH_OSF=y
# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
# CONFIG_NETFILTER_XT_MATCH_REALM is not set
CONFIG_NETFILTER_XT_MATCH_RECENT=y
# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
# CONFIG_NETFILTER_XT_MATCH_STRING is not set
CONFIG_NETFILTER_XT_MATCH_TCPMSS=y
# CONFIG_NETFILTER_XT_MATCH_TIME is not set
CONFIG_NETFILTER_XT_MATCH_U32=y
CONFIG_IP_SET=y
CONFIG_IP_SET_MAX=256
# CONFIG_IP_SET_BITMAP_IP is not set
# CONFIG_IP_SET_BITMAP_IPMAC is not set
# CONFIG_IP_SET_BITMAP_PORT is not set
CONFIG_IP_SET_HASH_IP=y
CONFIG_IP_SET_HASH_IPPORT=y
CONFIG_IP_SET_HASH_IPPORTIP=y
# CONFIG_IP_SET_HASH_IPPORTNET is not set
# CONFIG_IP_SET_HASH_NET is not set
# CONFIG_IP_SET_HASH_NETPORT is not set
CONFIG_IP_SET_HASH_NETIFACE=y
CONFIG_IP_SET_LIST_SET=y
CONFIG_IP_VS=y
# CONFIG_IP_VS_DEBUG is not set
CONFIG_IP_VS_TAB_BITS=12

#
# IPVS transport protocol load balancing support
#
CONFIG_IP_VS_PROTO_TCP=y
# CONFIG_IP_VS_PROTO_UDP is not set
CONFIG_IP_VS_PROTO_AH_ESP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
CONFIG_IP_VS_PROTO_SCTP=y

#
# IPVS scheduler
#
CONFIG_IP_VS_RR=y
CONFIG_IP_VS_WRR=y
# CONFIG_IP_VS_LC is not set
CONFIG_IP_VS_WLC=y
CONFIG_IP_VS_LBLC=y
CONFIG_IP_VS_LBLCR=y
CONFIG_IP_VS_DH=y
CONFIG_IP_VS_SH=y
# CONFIG_IP_VS_SED is not set
CONFIG_IP_VS_NQ=y

#
# IPVS SH scheduler
#
CONFIG_IP_VS_SH_TAB_BITS=8

#
# IPVS application helper
#

#
# IP: Netfilter Configuration
#
# CONFIG_NF_DEFRAG_IPV4 is not set
# CONFIG_IP_NF_QUEUE is not set
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_MATCH_AH=y
CONFIG_IP_NF_MATCH_ECN=y
CONFIG_IP_NF_MATCH_RPFILTER=y
# CONFIG_IP_NF_MATCH_TTL is not set
CONFIG_IP_NF_FILTER=y
# CONFIG_IP_NF_TARGET_REJECT is not set
CONFIG_IP_NF_TARGET_ULOG=y
# CONFIG_IP_NF_MANGLE is not set
# CONFIG_IP_NF_RAW is not set
CONFIG_IP_NF_SECURITY=y
CONFIG_IP_NF_ARPTABLES=y
# CONFIG_IP_NF_ARPFILTER is not set
# CONFIG_IP_NF_ARP_MANGLE is not set

#
# DECnet: Netfilter Configuration
#
CONFIG_DECNET_NF_GRABULATOR=y
CONFIG_IP_DCCP=y

#
# DCCP CCIDs Configuration (EXPERIMENTAL)
#
# CONFIG_IP_DCCP_CCID2_DEBUG is not set
CONFIG_IP_DCCP_CCID3=y
CONFIG_IP_DCCP_CCID3_DEBUG=y
CONFIG_IP_DCCP_TFRC_LIB=y
CONFIG_IP_DCCP_TFRC_DEBUG=y

#
# DCCP Kernel Hacking
#
CONFIG_IP_DCCP_DEBUG=y
# CONFIG_IP_SCTP is not set
# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_L2TP is not set
CONFIG_STP=y
CONFIG_GARP=y
# CONFIG_BRIDGE is not set
CONFIG_NET_DSA=y
CONFIG_NET_DSA_TAG_DSA=y
# CONFIG_NET_DSA_TAG_EDSA is not set
CONFIG_NET_DSA_TAG_TRAILER=y
CONFIG_VLAN_8021Q=y
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_DECNET=y
# CONFIG_DECNET_ROUTER is not set
CONFIG_LLC=y
# CONFIG_LLC2 is not set
CONFIG_IPX=y
CONFIG_IPX_INTERN=y
CONFIG_ATALK=y
CONFIG_DEV_APPLETALK=y
CONFIG_IPDDP=y
CONFIG_IPDDP_ENCAP=y
CONFIG_IPDDP_DECAP=y
# CONFIG_X25 is not set
CONFIG_LAPB=y
# CONFIG_WAN_ROUTER is not set
CONFIG_PHONET=y
# CONFIG_IEEE802154 is not set
CONFIG_NET_SCHED=y

#
# Queueing/Scheduling
#
CONFIG_NET_SCH_CBQ=y
CONFIG_NET_SCH_HTB=y
# CONFIG_NET_SCH_HFSC is not set
# CONFIG_NET_SCH_PRIO is not set
# CONFIG_NET_SCH_MULTIQ is not set
# CONFIG_NET_SCH_RED is not set
CONFIG_NET_SCH_SFB=y
# CONFIG_NET_SCH_SFQ is not set
# CONFIG_NET_SCH_TEQL is not set
CONFIG_NET_SCH_TBF=y
# CONFIG_NET_SCH_GRED is not set
CONFIG_NET_SCH_DSMARK=y
CONFIG_NET_SCH_NETEM=y
CONFIG_NET_SCH_DRR=y
# CONFIG_NET_SCH_MQPRIO is not set
CONFIG_NET_SCH_CHOKE=y
CONFIG_NET_SCH_QFQ=y
# CONFIG_NET_SCH_CODEL is not set
# CONFIG_NET_SCH_FQ_CODEL is not set
CONFIG_NET_SCH_PLUG=y

#
# Classification
#
CONFIG_NET_CLS=y
CONFIG_NET_CLS_BASIC=y
CONFIG_NET_CLS_TCINDEX=y
# CONFIG_NET_CLS_ROUTE4 is not set
CONFIG_NET_CLS_FW=y
# CONFIG_NET_CLS_U32 is not set
# CONFIG_NET_CLS_RSVP is not set
CONFIG_NET_CLS_RSVP6=y
CONFIG_NET_CLS_FLOW=y
# CONFIG_NET_EMATCH is not set
# CONFIG_NET_CLS_ACT is not set
CONFIG_NET_CLS_IND=y
CONFIG_NET_SCH_FIFO=y
# CONFIG_DCB is not set
# CONFIG_DNS_RESOLVER is not set
# CONFIG_BATMAN_ADV is not set
# CONFIG_OPENVSWITCH is not set
CONFIG_BQL=y

#
# Network testing
#
CONFIG_HAMRADIO=y

#
# Packet Radio protocols
#
# CONFIG_AX25 is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
CONFIG_BT=y
CONFIG_BT_RFCOMM=y
CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=y
CONFIG_BT_BNEP_MC_FILTER=y
# CONFIG_BT_BNEP_PROTO_FILTER is not set
# CONFIG_BT_HIDP is not set

#
# Bluetooth device drivers
#
CONFIG_BT_HCIBTSDIO=y
# CONFIG_BT_HCIUART is not set
CONFIG_BT_HCIVHCI=y
CONFIG_BT_MRVL=y
# CONFIG_BT_MRVL_SDIO is not set
# CONFIG_AF_RXRPC is not set
CONFIG_FIB_RULES=y
# CONFIG_WIRELESS is not set
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
CONFIG_NET_9P=y
CONFIG_NET_9P_VIRTIO=y
CONFIG_NET_9P_RDMA=y
CONFIG_NET_9P_DEBUG=y
CONFIG_CAIF=y
CONFIG_CAIF_DEBUG=y
# CONFIG_CAIF_NETDEV is not set
CONFIG_CAIF_USB=y
CONFIG_CEPH_LIB=y
CONFIG_CEPH_LIB_PRETTYDEBUG=y
# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set
# CONFIG_NFC is not set

#
# Device Drivers
#

#
# Generic Driver Options
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_GENERIC_CPU_DEVICES is not set
CONFIG_REGMAP=y
CONFIG_REGMAP_I2C=y
CONFIG_REGMAP_IRQ=y
# CONFIG_DMA_SHARED_BUFFER is not set
# CONFIG_CMA is not set

#
# Bus devices
#
# CONFIG_OMAP_OCP2SCP is not set
CONFIG_CONNECTOR=y
CONFIG_PROC_EVENTS=y
CONFIG_MTD=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
CONFIG_MTD_OF_PARTS=y
# CONFIG_MTD_AR7_PARTS is not set

#
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
CONFIG_HAVE_MTD_OTP=y
CONFIG_MTD_BLKDEVS=y
# CONFIG_MTD_BLOCK is not set
# CONFIG_MTD_BLOCK_RO is not set
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
CONFIG_INFTL=y
CONFIG_RFD_FTL=y
CONFIG_SSFDC=y
# CONFIG_SM_FTL is not set
CONFIG_MTD_OOPS=y

#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=y
# CONFIG_MTD_JEDECPROBE is not set
CONFIG_MTD_GEN_PROBE=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
# CONFIG_MTD_CFI_NOSWAP is not set
# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
CONFIG_MTD_CFI_LE_BYTE_SWAP=y
# CONFIG_MTD_CFI_GEOMETRY is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
CONFIG_MTD_OTP=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
CONFIG_MTD_ROM=y
# CONFIG_MTD_ABSENT is not set

#
# Mapping drivers for chip access
#
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_COMPAT=y
CONFIG_MTD_PHYSMAP_START=0x8000000
CONFIG_MTD_PHYSMAP_LEN=0
CONFIG_MTD_PHYSMAP_BANKWIDTH=2
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MTD_SC520CDP=y
# CONFIG_MTD_NETSC520 is not set
# CONFIG_MTD_TS5500 is not set
# CONFIG_MTD_SBC_GXX is not set
CONFIG_MTD_PCI=y
# CONFIG_MTD_GPIO_ADDR is not set
CONFIG_MTD_INTEL_VR_NOR=y
# CONFIG_MTD_PLATRAM is not set
CONFIG_MTD_LATCH_ADDR=y

#
# Self-contained MTD device drivers
#
# CONFIG_MTD_PMC551 is not set
CONFIG_MTD_SLRAM=y
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLOCK2MTD is not set

#
# Disk-On-Chip Device Drivers
#
# CONFIG_MTD_DOC2000 is not set
CONFIG_MTD_DOC2001=y
# CONFIG_MTD_DOC2001PLUS is not set
# CONFIG_MTD_DOCG3 is not set
CONFIG_MTD_DOCPROBE=y
CONFIG_MTD_DOCECC=y
# CONFIG_MTD_DOCPROBE_ADVANCED is not set
CONFIG_MTD_DOCPROBE_ADDRESS=0x0
CONFIG_MTD_NAND_ECC=y
# CONFIG_MTD_NAND_ECC_SMC is not set
CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_ECC_BCH is not set
CONFIG_MTD_SM_COMMON=y
CONFIG_MTD_NAND_MUSEUM_IDS=y
CONFIG_MTD_NAND_DENALI=y
CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018
CONFIG_MTD_NAND_IDS=y
CONFIG_MTD_NAND_RICOH=y
CONFIG_MTD_NAND_DISKONCHIP=y
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
# CONFIG_MTD_NAND_DOCG4 is not set
CONFIG_MTD_NAND_CAFE=y
# CONFIG_MTD_NAND_CS553X is not set
# CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_ONENAND is not set

#
# LPDDR flash memory drivers
#
CONFIG_MTD_LPDDR=y
CONFIG_MTD_QINFO_PROBE=y
# CONFIG_MTD_UBI is not set
CONFIG_OF=y

#
# Device Tree and Open Firmware support
#
# CONFIG_OF_SELFTEST is not set
CONFIG_OF_PROMTREE=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_IRQ=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_NET=y
CONFIG_OF_MDIO=y
CONFIG_OF_PCI=y
CONFIG_OF_PCI_IRQ=y
CONFIG_OF_MTD=y
CONFIG_PARPORT=y
# CONFIG_PARPORT_PC is not set
# CONFIG_PARPORT_GSC is not set
# CONFIG_PARPORT_AX88796 is not set
# CONFIG_PARPORT_1284 is not set
CONFIG_PNP=y
# CONFIG_PNP_DEBUG_MESSAGES is not set

#
# Protocols
#
CONFIG_PNPACPI=y
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
CONFIG_BLK_DEV_PCIESSD_MTIP32XX=y
CONFIG_BLK_CPQ_DA=y
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
# CONFIG_BLK_DEV_CRYPTOLOOP is not set

#
# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
#
# CONFIG_BLK_DEV_NBD is not set
CONFIG_BLK_DEV_NVME=y
# CONFIG_BLK_DEV_OSD is not set
# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_XIP=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
CONFIG_VIRTIO_BLK=y
CONFIG_BLK_DEV_HD=y
CONFIG_BLK_DEV_RBD=y

#
# Misc devices
#
# CONFIG_SENSORS_LIS3LV02D is not set
CONFIG_AD525X_DPOT=y
# CONFIG_AD525X_DPOT_I2C is not set
CONFIG_IBM_ASM=y
CONFIG_PHANTOM=y
# CONFIG_INTEL_MID_PTI is not set
CONFIG_SGI_IOC4=y
CONFIG_TIFM_CORE=y
# CONFIG_TIFM_7XX1 is not set
CONFIG_ICS932S401=y
CONFIG_ENCLOSURE_SERVICES=y
CONFIG_HP_ILO=y
CONFIG_APDS9802ALS=y
CONFIG_ISL29003=y
# CONFIG_ISL29020 is not set
CONFIG_SENSORS_TSL2550=y
# CONFIG_SENSORS_BH1780 is not set
# CONFIG_SENSORS_BH1770 is not set
# CONFIG_SENSORS_APDS990X is not set
# CONFIG_HMC6352 is not set
CONFIG_DS1682=y
CONFIG_VMWARE_BALLOON=y
CONFIG_BMP085=y
CONFIG_BMP085_I2C=y
# CONFIG_PCH_PHUB is not set
CONFIG_USB_SWITCH_FSA9480=y
# CONFIG_C2PORT is not set

#
# EEPROM support
#
CONFIG_EEPROM_AT24=y
CONFIG_EEPROM_LEGACY=y
# CONFIG_EEPROM_MAX6875 is not set
CONFIG_EEPROM_93CX6=y
CONFIG_CB710_CORE=y
CONFIG_CB710_DEBUG=y
CONFIG_CB710_DEBUG_ASSUMPTIONS=y

#
# Texas Instruments shared transport line discipline
#
# CONFIG_TI_ST is not set
# CONFIG_SENSORS_LIS3_I2C is not set

#
# Altera FPGA firmware download module
#
# CONFIG_ALTERA_STAPL is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set

#
# SCSI device support
#
CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set

#
# SCSI support type (disk, tape, CD-ROM)
#
# CONFIG_BLK_DEV_SD is not set
# CONFIG_CHR_DEV_ST is not set
CONFIG_CHR_DEV_OSST=y
# CONFIG_BLK_DEV_SR is not set
CONFIG_CHR_DEV_SG=y
CONFIG_CHR_DEV_SCH=y
# CONFIG_SCSI_ENCLOSURE is not set
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_SCAN_ASYNC is not set

#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
CONFIG_SCSI_ISCSI_ATTRS=y
CONFIG_SCSI_SAS_ATTRS=y
CONFIG_SCSI_SAS_LIBSAS=y
CONFIG_SCSI_SAS_ATA=y
CONFIG_SCSI_SAS_HOST_SMP=y
CONFIG_SCSI_SRP_ATTRS=y
# CONFIG_SCSI_LOWLEVEL is not set
# CONFIG_SCSI_DH is not set
CONFIG_SCSI_OSD_INITIATOR=y
CONFIG_SCSI_OSD_ULD=y
CONFIG_SCSI_OSD_DPRINT_SENSE=1
CONFIG_SCSI_OSD_DEBUG=y
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_ATA_ACPI=y
# CONFIG_SATA_PMP is not set

#
# Controllers with non-SFF native interface
#
CONFIG_SATA_AHCI=y
CONFIG_SATA_AHCI_PLATFORM=y
# CONFIG_SATA_INIC162X is not set
# CONFIG_SATA_ACARD_AHCI is not set
# CONFIG_SATA_SIL24 is not set
# CONFIG_ATA_SFF is not set
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
# CONFIG_MD_AUTODETECT is not set
CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
CONFIG_MD_RAID10=y
CONFIG_MD_RAID456=y
CONFIG_MD_MULTIPATH=y
CONFIG_MD_FAULTY=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_DEBUG=y
CONFIG_DM_BUFIO=y
CONFIG_DM_PERSISTENT_DATA=y
# CONFIG_DM_CRYPT is not set
# CONFIG_DM_SNAPSHOT is not set
CONFIG_DM_THIN_PROVISIONING=y
# CONFIG_DM_DEBUG_BLOCK_STACK_TRACING is not set
CONFIG_DM_MIRROR=y
CONFIG_DM_RAID=y
CONFIG_DM_LOG_USERSPACE=y
CONFIG_DM_ZERO=y
# CONFIG_DM_MULTIPATH is not set
# CONFIG_DM_DELAY is not set
# CONFIG_DM_UEVENT is not set
# CONFIG_DM_FLAKEY is not set
CONFIG_DM_VERITY=y
# CONFIG_TARGET_CORE is not set
CONFIG_FUSION=y
CONFIG_FUSION_SPI=y
# CONFIG_FUSION_FC is not set
CONFIG_FUSION_SAS=y
CONFIG_FUSION_MAX_SGE=128
# CONFIG_FUSION_CTL is not set
CONFIG_FUSION_LOGGING=y

#
# IEEE 1394 (FireWire) support
#
# CONFIG_FIREWIRE is not set
# CONFIG_FIREWIRE_NOSY is not set
CONFIG_I2O=y
CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y
# CONFIG_I2O_EXT_ADAPTEC is not set
CONFIG_I2O_CONFIG=y
CONFIG_I2O_CONFIG_OLD_IOCTL=y
CONFIG_I2O_BUS=y
# CONFIG_I2O_BLOCK is not set
CONFIG_I2O_SCSI=y
# CONFIG_I2O_PROC is not set
# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
CONFIG_NET_CORE=y
# CONFIG_BONDING is not set
# CONFIG_DUMMY is not set
CONFIG_EQUALIZER=y
CONFIG_NET_FC=y
# CONFIG_MII is not set
# CONFIG_NET_TEAM is not set
CONFIG_MACVLAN=y
CONFIG_MACVTAP=y
CONFIG_NETCONSOLE=y
# CONFIG_NETCONSOLE_DYNAMIC is not set
CONFIG_NETPOLL=y
# CONFIG_NETPOLL_TRAP is not set
CONFIG_NET_POLL_CONTROLLER=y
# CONFIG_RIONET is not set
# CONFIG_TUN is not set
CONFIG_VETH=y
CONFIG_VIRTIO_NET=y
# CONFIG_ARCNET is not set

#
# CAIF transport drivers
#
# CONFIG_CAIF_TTY is not set
# CONFIG_CAIF_SPI_SLAVE is not set
# CONFIG_CAIF_HSI is not set

#
# Distributed Switch Architecture drivers
#
CONFIG_NET_DSA_MV88E6XXX=y
CONFIG_NET_DSA_MV88E6060=y
CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y
CONFIG_NET_DSA_MV88E6131=y
# CONFIG_NET_DSA_MV88E6123_61_65 is not set
# CONFIG_ETHERNET is not set
# CONFIG_FDDI is not set
CONFIG_HIPPI=y
# CONFIG_ROADRUNNER is not set
# CONFIG_NET_SB1000 is not set
CONFIG_PHYLIB=y

#
# MII PHY device drivers
#
# CONFIG_AMD_PHY is not set
# CONFIG_MARVELL_PHY is not set
# CONFIG_DAVICOM_PHY is not set
CONFIG_QSEMI_PHY=y
# CONFIG_LXT_PHY is not set
# CONFIG_CICADA_PHY is not set
CONFIG_VITESSE_PHY=y
CONFIG_SMSC_PHY=y
# CONFIG_BROADCOM_PHY is not set
# CONFIG_BCM87XX_PHY is not set
# CONFIG_ICPLUS_PHY is not set
CONFIG_REALTEK_PHY=y
CONFIG_NATIONAL_PHY=y
# CONFIG_STE10XP is not set
# CONFIG_LSI_ET1011C_PHY is not set
CONFIG_MICREL_PHY=y
# CONFIG_FIXED_PHY is not set
# CONFIG_MDIO_BITBANG is not set
CONFIG_MDIO_BUS_MUX=y
# CONFIG_MDIO_BUS_MUX_GPIO is not set
CONFIG_MDIO_BUS_MUX_MMIOREG=y
# CONFIG_PLIP is not set
# CONFIG_PPP is not set
CONFIG_SLIP=y
CONFIG_SLHC=y
CONFIG_SLIP_COMPRESSED=y
# CONFIG_SLIP_SMART is not set
# CONFIG_SLIP_MODE_SLIP6 is not set
# CONFIG_WLAN is not set

#
# Enable WiMAX (Networking options) to see the WiMAX drivers
#
# CONFIG_WAN is not set
# CONFIG_VMXNET3 is not set
# CONFIG_ISDN is not set

#
# Input device support
#
CONFIG_INPUT=y
CONFIG_INPUT_FF_MEMLESS=y
# CONFIG_INPUT_POLLDEV is not set
# CONFIG_INPUT_SPARSEKMAP is not set
CONFIG_INPUT_MATRIXKMAP=y

#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_INPUT_JOYDEV=y
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=y

#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
# CONFIG_KEYBOARD_ADP5520 is not set
# CONFIG_KEYBOARD_ADP5588 is not set
# CONFIG_KEYBOARD_ADP5589 is not set
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_QT1070 is not set
CONFIG_KEYBOARD_QT2160=y
CONFIG_KEYBOARD_LKKBD=y
CONFIG_KEYBOARD_GPIO=y
# CONFIG_KEYBOARD_GPIO_POLLED is not set
CONFIG_KEYBOARD_TCA6416=y
CONFIG_KEYBOARD_TCA8418=y
# CONFIG_KEYBOARD_MATRIX is not set
# CONFIG_KEYBOARD_LM8333 is not set
# CONFIG_KEYBOARD_MAX7359 is not set
# CONFIG_KEYBOARD_MCS is not set
# CONFIG_KEYBOARD_MPR121 is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_STMPE is not set
CONFIG_KEYBOARD_OMAP4=y
# CONFIG_KEYBOARD_XTKBD is not set
CONFIG_INPUT_MOUSE=y
# CONFIG_MOUSE_PS2 is not set
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_MOUSE_GPIO is not set
CONFIG_MOUSE_SYNAPTICS_I2C=y
CONFIG_INPUT_JOYSTICK=y
# CONFIG_JOYSTICK_ANALOG is not set
# CONFIG_JOYSTICK_A3D is not set
# CONFIG_JOYSTICK_ADI is not set
CONFIG_JOYSTICK_COBRA=y
# CONFIG_JOYSTICK_GF2K is not set
CONFIG_JOYSTICK_GRIP=y
# CONFIG_JOYSTICK_GRIP_MP is not set
# CONFIG_JOYSTICK_GUILLEMOT is not set
CONFIG_JOYSTICK_INTERACT=y
CONFIG_JOYSTICK_SIDEWINDER=y
CONFIG_JOYSTICK_TMDC=y
# CONFIG_JOYSTICK_IFORCE is not set
# CONFIG_JOYSTICK_WARRIOR is not set
# CONFIG_JOYSTICK_MAGELLAN is not set
CONFIG_JOYSTICK_SPACEORB=y
# CONFIG_JOYSTICK_SPACEBALL is not set
CONFIG_JOYSTICK_STINGER=y
CONFIG_JOYSTICK_TWIDJOY=y
CONFIG_JOYSTICK_ZHENHUA=y
# CONFIG_JOYSTICK_DB9 is not set
CONFIG_JOYSTICK_GAMECON=y
CONFIG_JOYSTICK_TURBOGRAFX=y
# CONFIG_JOYSTICK_AS5011 is not set
# CONFIG_JOYSTICK_JOYDUMP is not set
# CONFIG_JOYSTICK_WALKERA0701 is not set
CONFIG_INPUT_TABLET=y
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set

#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PARKBD is not set
# CONFIG_SERIO_PCIPS2 is not set
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=y
CONFIG_SERIO_ALTERA_PS2=y
CONFIG_SERIO_PS2MULT=y
CONFIG_GAMEPORT=y
# CONFIG_GAMEPORT_NS558 is not set
# CONFIG_GAMEPORT_L4 is not set
# CONFIG_GAMEPORT_EMU10K1 is not set
CONFIG_GAMEPORT_FM801=y

#
# Character devices
#
# CONFIG_VT is not set
# CONFIG_UNIX98_PTYS is not set
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_NONSTANDARD=y
CONFIG_ROCKETPORT=y
CONFIG_CYCLADES=y
CONFIG_CYZ_INTR=y
CONFIG_MOXA_INTELLIO=y
# CONFIG_MOXA_SMARTIO is not set
CONFIG_SYNCLINK=y
CONFIG_SYNCLINKMP=y
# CONFIG_SYNCLINK_GT is not set
CONFIG_NOZOMI=y
CONFIG_ISI=y
CONFIG_N_HDLC=y
CONFIG_N_GSM=y
# CONFIG_TRACE_ROUTER is not set
CONFIG_TRACE_SINK=y
# CONFIG_DEVKMEM is not set
# CONFIG_STALDRV is not set

#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_FIX_EARLYCON_MEM=y
# CONFIG_SERIAL_8250_PCI is not set
CONFIG_SERIAL_8250_PNP=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
# CONFIG_SERIAL_8250_SHARE_IRQ is not set
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
# CONFIG_SERIAL_8250_RSA is not set
CONFIG_SERIAL_8250_DW=y

#
# Non-8250 serial port support
#
# CONFIG_SERIAL_MFD_HSU is not set
CONFIG_SERIAL_UARTLITE=y
CONFIG_SERIAL_UARTLITE_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_CONSOLE_POLL=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
# CONFIG_SERIAL_TIMBERDALE is not set
CONFIG_SERIAL_ALTERA_JTAGUART=y
# CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE is not set
# CONFIG_SERIAL_ALTERA_UART is not set
CONFIG_SERIAL_PCH_UART=y
CONFIG_SERIAL_PCH_UART_CONSOLE=y
# CONFIG_SERIAL_XILINX_PS_UART is not set
CONFIG_TTY_PRINTK=y
# CONFIG_PRINTER is not set
CONFIG_PPDEV=y
CONFIG_HVC_DRIVER=y
CONFIG_VIRTIO_CONSOLE=y
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_TIMERIOMEM=y
CONFIG_HW_RANDOM_INTEL=y
CONFIG_HW_RANDOM_AMD=y
CONFIG_HW_RANDOM_GEODE=y
CONFIG_HW_RANDOM_VIA=y
# CONFIG_HW_RANDOM_VIRTIO is not set
CONFIG_HW_RANDOM_TPM=y
CONFIG_NVRAM=y
# CONFIG_RTC is not set
# CONFIG_GEN_RTC is not set
CONFIG_R3964=y
CONFIG_APPLICOM=y
CONFIG_SONYPI=y
# CONFIG_MWAVE is not set
# CONFIG_PC8736x_GPIO is not set
# CONFIG_NSC_GPIO is not set
# CONFIG_RAW_DRIVER is not set
CONFIG_HPET=y
CONFIG_HPET_MMAP=y
CONFIG_HANGCHECK_TIMER=y
CONFIG_TCG_TPM=y
CONFIG_TCG_TIS=y
# CONFIG_TCG_TIS_I2C_INFINEON is not set
# CONFIG_TCG_NSC is not set
# CONFIG_TCG_ATMEL is not set
# CONFIG_TCG_INFINEON is not set
# CONFIG_TELCLOCK is not set
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
# CONFIG_I2C_COMPAT is not set
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MUX=y

#
# Multiplexer I2C Chip support
#
CONFIG_I2C_MUX_GPIO=y
# CONFIG_I2C_MUX_PCA9541 is not set
CONFIG_I2C_MUX_PCA954x=y
# CONFIG_I2C_HELPER_AUTO is not set
CONFIG_I2C_SMBUS=y

#
# I2C Algorithms
#
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_ALGOPCF=y
# CONFIG_I2C_ALGOPCA is not set

#
# I2C Hardware Bus support
#

#
# PC SMBus host controller drivers
#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
# CONFIG_I2C_AMD756 is not set
# CONFIG_I2C_AMD8111 is not set
CONFIG_I2C_I801=y
# CONFIG_I2C_ISCH is not set
CONFIG_I2C_PIIX4=y
CONFIG_I2C_NFORCE2=y
# CONFIG_I2C_NFORCE2_S4985 is not set
CONFIG_I2C_SIS5595=y
CONFIG_I2C_SIS630=y
# CONFIG_I2C_SIS96X is not set
CONFIG_I2C_VIA=y
# CONFIG_I2C_VIAPRO is not set

#
# ACPI drivers
#
# CONFIG_I2C_SCMI is not set

#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
# CONFIG_I2C_DESIGNWARE_PCI is not set
CONFIG_I2C_EG20T=y
# CONFIG_I2C_GPIO is not set
# CONFIG_I2C_INTEL_MID is not set
CONFIG_I2C_OCORES=y
# CONFIG_I2C_PCA_PLATFORM is not set
CONFIG_I2C_PXA=y
CONFIG_I2C_PXA_PCI=y
CONFIG_I2C_SIMTEC=y
# CONFIG_I2C_XILINX is not set

#
# External I2C/SMBus adapter drivers
#
CONFIG_I2C_PARPORT=y
CONFIG_I2C_PARPORT_LIGHT=y
CONFIG_I2C_TAOS_EVM=y

#
# Other I2C/SMBus bus drivers
#
# CONFIG_SCx200_ACB is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
CONFIG_I2C_DEBUG_BUS=y
# CONFIG_SPI is not set
CONFIG_HSI=y
CONFIG_HSI_BOARDINFO=y

#
# HSI clients
#
# CONFIG_HSI_CHAR is not set

#
# PPS support
#
# CONFIG_PPS is not set

#
# PPS generators support
#

#
# PTP clock support
#

#
# Enable Device Drivers -> PPS to see the PTP clock options.
#
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIOLIB=y
CONFIG_OF_GPIO=y
CONFIG_DEBUG_GPIO=y
# CONFIG_GPIO_SYSFS is not set
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_MAX730X=y

#
# Memory mapped GPIO drivers:
#
# CONFIG_GPIO_GENERIC_PLATFORM is not set
# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_SCH is not set
CONFIG_GPIO_ICH=y
CONFIG_GPIO_VX855=y

#
# I2C GPIO expanders:
#
CONFIG_GPIO_MAX7300=y
CONFIG_GPIO_MAX732X=y
CONFIG_GPIO_MAX732X_IRQ=y
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCA953X_IRQ=y
# CONFIG_GPIO_PCF857X is not set
CONFIG_GPIO_RC5T583=y
# CONFIG_GPIO_SX150X is not set
CONFIG_GPIO_STMPE=y
CONFIG_GPIO_TPS65912=y
CONFIG_GPIO_WM8350=y
# CONFIG_GPIO_WM8994 is not set
# CONFIG_GPIO_ADP5520 is not set
CONFIG_GPIO_ADP5588=y
# CONFIG_GPIO_ADP5588_IRQ is not set

#
# PCI GPIO expanders:
#
CONFIG_GPIO_BT8XX=y
CONFIG_GPIO_AMD8111=y
# CONFIG_GPIO_LANGWELL is not set
CONFIG_GPIO_PCH=y
# CONFIG_GPIO_ML_IOH is not set
CONFIG_GPIO_SODAVILLE=y
# CONFIG_GPIO_TIMBERDALE is not set
# CONFIG_GPIO_RDC321X is not set

#
# SPI GPIO expanders:
#
CONFIG_GPIO_MCP23S08=y

#
# AC97 GPIO expanders:
#

#
# MODULbus GPIO expanders:
#
CONFIG_GPIO_JANZ_TTL=y
# CONFIG_GPIO_TPS65910 is not set
CONFIG_W1=y
CONFIG_W1_CON=y

#
# 1-wire Bus Masters
#
CONFIG_W1_MASTER_MATROX=y
# CONFIG_W1_MASTER_DS2482 is not set
CONFIG_W1_MASTER_DS1WM=y
# CONFIG_W1_MASTER_GPIO is not set
# CONFIG_HDQ_MASTER_OMAP is not set

#
# 1-wire Slaves
#
# CONFIG_W1_SLAVE_THERM is not set
# CONFIG_W1_SLAVE_SMEM is not set
# CONFIG_W1_SLAVE_DS2408 is not set
CONFIG_W1_SLAVE_DS2423=y
CONFIG_W1_SLAVE_DS2431=y
# CONFIG_W1_SLAVE_DS2433 is not set
CONFIG_W1_SLAVE_DS2760=y
CONFIG_W1_SLAVE_DS2780=y
CONFIG_W1_SLAVE_DS2781=y
# CONFIG_W1_SLAVE_DS28E04 is not set
CONFIG_W1_SLAVE_BQ27000=y
CONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
CONFIG_PDA_POWER=y
# CONFIG_WM8350_POWER is not set
CONFIG_TEST_POWER=y
CONFIG_BATTERY_DS2760=y
# CONFIG_BATTERY_DS2780 is not set
CONFIG_BATTERY_DS2781=y
CONFIG_BATTERY_DS2782=y
CONFIG_BATTERY_OLPC=y
CONFIG_BATTERY_SBS=y
CONFIG_BATTERY_BQ27x00=y
# CONFIG_BATTERY_BQ27X00_I2C is not set
CONFIG_BATTERY_BQ27X00_PLATFORM=y
# CONFIG_BATTERY_DA9030 is not set
# CONFIG_BATTERY_MAX17040 is not set
CONFIG_BATTERY_MAX17042=y
# CONFIG_CHARGER_MAX8903 is not set
# CONFIG_CHARGER_LP8727 is not set
CONFIG_CHARGER_GPIO=y
CONFIG_CHARGER_SMB347=y
# CONFIG_POWER_AVS is not set
CONFIG_HWMON=y
CONFIG_HWMON_VID=y
# CONFIG_HWMON_DEBUG_CHIP is not set

#
# Native drivers
#
# CONFIG_SENSORS_ABITUGURU is not set
# CONFIG_SENSORS_ABITUGURU3 is not set
# CONFIG_SENSORS_AD7414 is not set
CONFIG_SENSORS_AD7418=y
CONFIG_SENSORS_ADM1021=y
# CONFIG_SENSORS_ADM1025 is not set
CONFIG_SENSORS_ADM1026=y
# CONFIG_SENSORS_ADM1029 is not set
CONFIG_SENSORS_ADM1031=y
CONFIG_SENSORS_ADM9240=y
CONFIG_SENSORS_ADT7410=y
# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
CONFIG_SENSORS_ADT7470=y
CONFIG_SENSORS_ADT7475=y
CONFIG_SENSORS_ASC7621=y
CONFIG_SENSORS_K8TEMP=y
CONFIG_SENSORS_K10TEMP=y
# CONFIG_SENSORS_FAM15H_POWER is not set
CONFIG_SENSORS_ASB100=y
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS620 is not set
CONFIG_SENSORS_DS1621=y
# CONFIG_SENSORS_I5K_AMB is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_F75375S is not set
# CONFIG_SENSORS_FSCHMD is not set
# CONFIG_SENSORS_G760A is not set
CONFIG_SENSORS_GL518SM=y
CONFIG_SENSORS_GL520SM=y
CONFIG_SENSORS_GPIO_FAN=y
# CONFIG_SENSORS_HIH6130 is not set
CONFIG_SENSORS_CORETEMP=y
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_JC42 is not set
CONFIG_SENSORS_LINEAGE=y
# CONFIG_SENSORS_LM63 is not set
# CONFIG_SENSORS_LM73 is not set
# CONFIG_SENSORS_LM75 is not set
CONFIG_SENSORS_LM77=y
# CONFIG_SENSORS_LM78 is not set
CONFIG_SENSORS_LM80=y
# CONFIG_SENSORS_LM83 is not set
# CONFIG_SENSORS_LM85 is not set
# CONFIG_SENSORS_LM87 is not set
# CONFIG_SENSORS_LM90 is not set
CONFIG_SENSORS_LM92=y
CONFIG_SENSORS_LM93=y
# CONFIG_SENSORS_LTC4151 is not set
CONFIG_SENSORS_LTC4215=y
# CONFIG_SENSORS_LTC4245 is not set
# CONFIG_SENSORS_LTC4261 is not set
CONFIG_SENSORS_LM95241=y
CONFIG_SENSORS_LM95245=y
# CONFIG_SENSORS_MAX16065 is not set
CONFIG_SENSORS_MAX1619=y
# CONFIG_SENSORS_MAX1668 is not set
CONFIG_SENSORS_MAX197=y
CONFIG_SENSORS_MAX6639=y
# CONFIG_SENSORS_MAX6642 is not set
# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_MCP3021 is not set
CONFIG_SENSORS_NTC_THERMISTOR=y
# CONFIG_SENSORS_PC87360 is not set
CONFIG_SENSORS_PC87427=y
CONFIG_SENSORS_PCF8591=y
# CONFIG_PMBUS is not set
CONFIG_SENSORS_SHT15=y
CONFIG_SENSORS_SHT21=y
# CONFIG_SENSORS_SIS5595 is not set
CONFIG_SENSORS_SMM665=y
# CONFIG_SENSORS_DME1737 is not set
CONFIG_SENSORS_EMC1403=y
CONFIG_SENSORS_EMC2103=y
# CONFIG_SENSORS_EMC6W201 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
CONFIG_SENSORS_SMSC47M192=y
CONFIG_SENSORS_SMSC47B397=y
# CONFIG_SENSORS_SCH56XX_COMMON is not set
# CONFIG_SENSORS_ADS1015 is not set
CONFIG_SENSORS_ADS7828=y
# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_INA2XX is not set
# CONFIG_SENSORS_THMC50 is not set
CONFIG_SENSORS_TMP102=y
# CONFIG_SENSORS_TMP401 is not set
CONFIG_SENSORS_TMP421=y
CONFIG_SENSORS_VIA_CPUTEMP=y
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
CONFIG_SENSORS_VT8231=y
CONFIG_SENSORS_W83781D=y
# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83795 is not set
# CONFIG_SENSORS_W83L785TS is not set
CONFIG_SENSORS_W83L786NG=y
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
CONFIG_SENSORS_WM8350=y
# CONFIG_SENSORS_APPLESMC is not set
CONFIG_SENSORS_MC13783_ADC=y

#
# ACPI drivers
#
# CONFIG_SENSORS_ACPI_POWER is not set
CONFIG_SENSORS_ATK0110=y
CONFIG_THERMAL=y
CONFIG_THERMAL_HWMON=y
# CONFIG_CPU_THERMAL is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y

#
# Sonics Silicon Backplane
#
CONFIG_SSB=y
CONFIG_SSB_SPROM=y
CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_PCIHOST=y
# CONFIG_SSB_B43_PCI_BRIDGE is not set
CONFIG_SSB_SDIOHOST_POSSIBLE=y
CONFIG_SSB_SDIOHOST=y
# CONFIG_SSB_SILENT is not set
CONFIG_SSB_DEBUG=y
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
# CONFIG_SSB_DRIVER_PCICORE is not set
CONFIG_BCMA_POSSIBLE=y

#
# Broadcom specific AMBA
#
CONFIG_BCMA=y
CONFIG_BCMA_HOST_PCI_POSSIBLE=y
CONFIG_BCMA_HOST_PCI=y
# CONFIG_BCMA_DRIVER_GMAC_CMN is not set
# CONFIG_BCMA_DEBUG is not set

#
# Multifunction device drivers
#
CONFIG_MFD_CORE=y
# CONFIG_MFD_88PM860X is not set
# CONFIG_MFD_88PM800 is not set
CONFIG_MFD_88PM805=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
CONFIG_HTC_I2CPLD=y
# CONFIG_MFD_LM3533 is not set
# CONFIG_TPS6105X is not set
# CONFIG_TPS65010 is not set
CONFIG_TPS6507X=y
CONFIG_MFD_TPS65217=y
CONFIG_MFD_TPS65910=y
CONFIG_MFD_TPS65912=y
CONFIG_MFD_TPS65912_I2C=y
# CONFIG_TWL4030_CORE is not set
CONFIG_TWL6040_CORE=y
CONFIG_MFD_STMPE=y

#
# STMPE Interface Drivers
#
CONFIG_STMPE_I2C=y
# CONFIG_MFD_TC3589X is not set
# CONFIG_MFD_TMIO is not set
CONFIG_PMIC_DA903X=y
# CONFIG_MFD_DA9052_I2C is not set
CONFIG_PMIC_ADP5520=y
CONFIG_MFD_MAX77686=y
CONFIG_MFD_MAX77693=y
# CONFIG_MFD_MAX8925 is not set
# CONFIG_MFD_MAX8997 is not set
CONFIG_MFD_MAX8998=y
# CONFIG_MFD_SEC_CORE is not set
# CONFIG_MFD_ARIZONA_I2C is not set
CONFIG_MFD_WM8400=y
# CONFIG_MFD_WM831X_I2C is not set
CONFIG_MFD_WM8350=y
CONFIG_MFD_WM8350_I2C=y
CONFIG_MFD_WM8994=y
# CONFIG_MFD_PCF50633 is not set
CONFIG_MFD_MC13783=y
CONFIG_MFD_MC13XXX=y
CONFIG_MFD_MC13XXX_I2C=y
CONFIG_ABX500_CORE=y
# CONFIG_AB3100_CORE is not set
# CONFIG_MFD_CS5535 is not set
CONFIG_MFD_TIMBERDALE=y
# CONFIG_LPC_SCH is not set
CONFIG_LPC_ICH=y
# CONFIG_MFD_RDC321X is not set
CONFIG_MFD_JANZ_CMODIO=y
CONFIG_MFD_VX855=y
CONFIG_MFD_WL1273_CORE=y
CONFIG_MFD_TPS65090=y
# CONFIG_MFD_AAT2870_CORE is not set
CONFIG_MFD_RC5T583=y
# CONFIG_MFD_PALMAS is not set
# CONFIG_REGULATOR is not set
CONFIG_MEDIA_SUPPORT=y

#
# Multimedia core support
#
# CONFIG_MEDIA_CAMERA_SUPPORT is not set
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
CONFIG_MEDIA_RADIO_SUPPORT=y
# CONFIG_MEDIA_RC_SUPPORT is not set
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_V4L2=y
# CONFIG_VIDEO_ADV_DEBUG is not set
CONFIG_VIDEO_FIXED_MINOR_RANGES=y

#
# Media drivers
#
# CONFIG_MEDIA_PCI_SUPPORT is not set

#
# Supported MMC/SDIO adapters
#
CONFIG_RADIO_ADAPTERS=y
CONFIG_RADIO_SI470X=y
# CONFIG_I2C_SI470X is not set
# CONFIG_I2C_SI4713 is not set
# CONFIG_RADIO_SI4713 is not set
CONFIG_RADIO_TEA5764=y
CONFIG_RADIO_TEA5764_XTAL=y
# CONFIG_RADIO_SAA7706H is not set
CONFIG_RADIO_TEF6862=y
# CONFIG_RADIO_TIMBERDALE is not set
# CONFIG_RADIO_WL1273 is not set

#
# Texas Instruments WL128x FM driver (ST based)
#
CONFIG_MEDIA_SUBDRV_AUTOSELECT=y

#
# Media ancillary drivers (tuners, sensors, i2c, frontends)
#

#
# Audio decoders, processors and mixers
#

#
# RDS decoders
#

#
# Video decoders
#

#
# Video and audio decoders
#

#
# MPEG video encoders
#

#
# Video encoders
#

#
# Camera sensor devices
#

#
# Flash devices
#

#
# Video improvement chips
#

#
# Miscelaneous helper chips
#

#
# Sensors used on soc_camera driver
#
CONFIG_MEDIA_TUNER=y
CONFIG_MEDIA_TUNER_SIMPLE=y
CONFIG_MEDIA_TUNER_TDA8290=y
CONFIG_MEDIA_TUNER_TDA827X=y
CONFIG_MEDIA_TUNER_TDA18271=y
CONFIG_MEDIA_TUNER_TDA9887=y
CONFIG_MEDIA_TUNER_TEA5761=y
CONFIG_MEDIA_TUNER_TEA5767=y
CONFIG_MEDIA_TUNER_MT20XX=y
CONFIG_MEDIA_TUNER_XC2028=y
CONFIG_MEDIA_TUNER_XC5000=y
CONFIG_MEDIA_TUNER_XC4000=y
CONFIG_MEDIA_TUNER_MC44S803=y

#
# Tools to develop new frontends
#
# CONFIG_DVB_DUMMY_FE is not set

#
# Graphics support
#
# CONFIG_AGP is not set
# CONFIG_VGA_ARB is not set
# CONFIG_VGA_SWITCHEROO is not set
# CONFIG_DRM is not set
CONFIG_STUB_POULSBO=y
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_FB is not set
# CONFIG_EXYNOS_VIDEO is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_SOUND=y
# CONFIG_SOUND_OSS_CORE is not set
# CONFIG_SND is not set
# CONFIG_SOUND_PRIME is not set

#
# HID support
#
CONFIG_HID=y
# CONFIG_HID_BATTERY_STRENGTH is not set
# CONFIG_HIDRAW is not set
CONFIG_UHID=y
# CONFIG_HID_GENERIC is not set

#
# Special HID drivers
#
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB_ARCH_HAS_XHCI=y
# CONFIG_USB_SUPPORT is not set
CONFIG_UWB=y
# CONFIG_UWB_WHCI is not set
CONFIG_MMC=y
CONFIG_MMC_DEBUG=y
CONFIG_MMC_UNSAFE_RESUME=y
CONFIG_MMC_CLKGATE=y

#
# MMC/SD/SDIO Card Drivers
#
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_MINORS=8
# CONFIG_MMC_BLOCK_BOUNCE is not set
# CONFIG_SDIO_UART is not set
CONFIG_MMC_TEST=y

#
# MMC/SD/SDIO Host Controller Drivers
#
# CONFIG_MMC_SDHCI is not set
CONFIG_MMC_WBSD=y
# CONFIG_MMC_TIFM_SD is not set
CONFIG_MMC_CB710=y
# CONFIG_MMC_VIA_SDMMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
CONFIG_ACCESSIBILITY=y
CONFIG_INFINIBAND=y
CONFIG_INFINIBAND_USER_MAD=y
# CONFIG_INFINIBAND_USER_ACCESS is not set
CONFIG_INFINIBAND_ADDR_TRANS=y
# CONFIG_INFINIBAND_MTHCA is not set
CONFIG_INFINIBAND_AMSO1100=y
CONFIG_INFINIBAND_AMSO1100_DEBUG=y
# CONFIG_INFINIBAND_NES is not set
# CONFIG_INFINIBAND_IPOIB is not set
# CONFIG_INFINIBAND_SRP is not set
# CONFIG_INFINIBAND_ISER is not set
# CONFIG_EDAC is not set
# CONFIG_RTC_CLASS is not set
CONFIG_DMADEVICES=y
# CONFIG_DMADEVICES_DEBUG is not set

#
# DMA Devices
#
# CONFIG_INTEL_MID_DMAC is not set
CONFIG_INTEL_IOATDMA=y
# CONFIG_TIMB_DMA is not set
# CONFIG_PCH_DMA is not set
CONFIG_DMA_ENGINE=y

#
# DMA Clients
#
# CONFIG_NET_DMA is not set
# CONFIG_ASYNC_TX_DMA is not set
# CONFIG_DMATEST is not set
CONFIG_DCA=y
CONFIG_AUXDISPLAY=y
# CONFIG_UIO is not set
CONFIG_VFIO_IOMMU_TYPE1=y
CONFIG_VFIO=y
CONFIG_VIRTIO=y
CONFIG_VIRTIO_RING=y

#
# Virtio drivers
#
CONFIG_VIRTIO_PCI=y
# CONFIG_VIRTIO_BALLOON is not set
CONFIG_VIRTIO_MMIO=y
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y

#
# Microsoft Hyper-V guest support
#
# CONFIG_HYPERV is not set
# CONFIG_STAGING is not set
# CONFIG_X86_PLATFORM_DEVICES is not set

#
# Hardware Spinlock drivers
#
CONFIG_CLKSRC_I8253=y
CONFIG_CLKEVT_I8253=y
CONFIG_CLKBLD_I8253=y
CONFIG_IOMMU_API=y
CONFIG_IOMMU_SUPPORT=y
CONFIG_OF_IOMMU=y
CONFIG_DMAR_TABLE=y
CONFIG_INTEL_IOMMU=y
CONFIG_INTEL_IOMMU_DEFAULT_ON=y
CONFIG_INTEL_IOMMU_FLOPPY_WA=y

#
# Remoteproc drivers (EXPERIMENTAL)
#

#
# Rpmsg drivers (EXPERIMENTAL)
#
# CONFIG_VIRT_DRIVERS is not set
# CONFIG_PM_DEVFREQ is not set
# CONFIG_EXTCON is not set
# CONFIG_MEMORY is not set
# CONFIG_IIO is not set
CONFIG_VME_BUS=y

#
# VME Bridge Drivers
#
CONFIG_VME_CA91CX42=y
CONFIG_VME_TSI148=y

#
# VME Board Drivers
#
CONFIG_VMIVME_7805=y

#
# VME Device Drivers
#
CONFIG_PWM=y

#
# Firmware Drivers
#
CONFIG_EDD=y
CONFIG_EDD_OFF=y
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_EFI_VARS=y
CONFIG_DELL_RBU=y
CONFIG_DCDBAS=y
CONFIG_DMIID=y
# CONFIG_DMI_SYSFS is not set
CONFIG_ISCSI_IBFT_FIND=y
# CONFIG_GOOGLE_FIRMWARE is not set

#
# File systems
#
CONFIG_DCACHE_WORD_ACCESS=y
# CONFIG_EXT2_FS is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
# CONFIG_EXT3_FS_SECURITY is not set
CONFIG_EXT4_FS=y
# CONFIG_EXT4_USE_FOR_EXT23 is not set
CONFIG_EXT4_FS_XATTR=y
# CONFIG_EXT4_FS_POSIX_ACL is not set
CONFIG_EXT4_FS_SECURITY=y
# CONFIG_EXT4_DEBUG is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_JBD2=y
CONFIG_JBD2_DEBUG=y
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
CONFIG_NILFS2_FS=y
CONFIG_FS_POSIX_ACL=y
CONFIG_EXPORTFS=y
CONFIG_FILE_LOCKING=y
# CONFIG_FSNOTIFY is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
# CONFIG_FANOTIFY is not set
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_PRINT_QUOTA_WARNING=y
CONFIG_QUOTA_DEBUG=y
CONFIG_QUOTA_TREE=y
# CONFIG_QFMT_V1 is not set
CONFIG_QFMT_V2=y
CONFIG_QUOTACTL=y
# CONFIG_AUTOFS4_FS is not set
CONFIG_FUSE_FS=y
# CONFIG_CUSE is not set

#
# Caches
#
CONFIG_FSCACHE=y
CONFIG_FSCACHE_DEBUG=y
# CONFIG_CACHEFILES is not set

#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
CONFIG_UDF_FS=y
CONFIG_UDF_NLS=y

#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
# CONFIG_MSDOS_FS is not set
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_NTFS_FS=y
# CONFIG_NTFS_DEBUG is not set
# CONFIG_NTFS_RW is not set

#
# Pseudo filesystems
#
# CONFIG_PROC_FS is not set
CONFIG_SYSFS=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_CONFIGFS_FS=y
# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V2=y
# CONFIG_NFS_V3 is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_SWAP is not set
# CONFIG_ROOT_NFS is not set
# CONFIG_NFS_FSCACHE is not set
# CONFIG_NFSD is not set
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_XPRT_RDMA=y
CONFIG_CEPH_FS=y
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
CONFIG_9P_FS=y
CONFIG_9P_FSCACHE=y
# CONFIG_9P_FS_POSIX_ACL is not set
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=y
# CONFIG_NLS_CODEPAGE_775 is not set
CONFIG_NLS_CODEPAGE_850=y
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
CONFIG_NLS_CODEPAGE_860=y
CONFIG_NLS_CODEPAGE_861=y
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
CONFIG_NLS_CODEPAGE_865=y
# CONFIG_NLS_CODEPAGE_866 is not set
CONFIG_NLS_CODEPAGE_869=y
CONFIG_NLS_CODEPAGE_936=y
# CONFIG_NLS_CODEPAGE_950 is not set
CONFIG_NLS_CODEPAGE_932=y
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
CONFIG_NLS_ISO8859_8=y
CONFIG_NLS_CODEPAGE_1250=y
CONFIG_NLS_CODEPAGE_1251=y
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=y
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
CONFIG_NLS_ISO8859_6=y
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
CONFIG_NLS_ISO8859_14=y
CONFIG_NLS_ISO8859_15=y
# CONFIG_NLS_KOI8_R is not set
CONFIG_NLS_KOI8_U=y
# CONFIG_NLS_MAC_ROMAN is not set
CONFIG_NLS_MAC_CELTIC=y
CONFIG_NLS_MAC_CENTEURO=y
CONFIG_NLS_MAC_CROATIAN=y
# CONFIG_NLS_MAC_CYRILLIC is not set
# CONFIG_NLS_MAC_GAELIC is not set
# CONFIG_NLS_MAC_GREEK is not set
CONFIG_NLS_MAC_ICELAND=y
# CONFIG_NLS_MAC_INUIT is not set
# CONFIG_NLS_MAC_ROMANIAN is not set
# CONFIG_NLS_MAC_TURKISH is not set
CONFIG_NLS_UTF8=y
# CONFIG_DLM is not set

#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_READABLE_ASM is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
CONFIG_HEADERS_CHECK=y
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_SHIRQ=y
# CONFIG_LOCKUP_DETECTOR is not set
# CONFIG_HARDLOCKUP_DETECTOR is not set
# CONFIG_PANIC_ON_OOPS is not set
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
# CONFIG_DEBUG_OBJECTS is not set
CONFIG_SLUB_DEBUG_ON=y
CONFIG_SLUB_STATS=y
# CONFIG_DEBUG_KMEMLEAK is not set
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_PI_LIST=y
CONFIG_RT_MUTEX_TESTER=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=y
# CONFIG_PROVE_RCU is not set
CONFIG_SPARSE_RCU_POINTER=y
CONFIG_LOCKDEP=y
# CONFIG_LOCK_STAT is not set
CONFIG_DEBUG_LOCKDEP=y
CONFIG_TRACE_IRQFLAGS=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
CONFIG_STACKTRACE=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_KOBJECT=y
# CONFIG_DEBUG_HIGHMEM is not set
# CONFIG_DEBUG_INFO is not set
CONFIG_DEBUG_VM=y
# CONFIG_DEBUG_VIRTUAL is not set
CONFIG_DEBUG_WRITECOUNT=y
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_DEBUG_LIST is not set
CONFIG_TEST_LIST_SORT=y
# CONFIG_DEBUG_SG is not set
CONFIG_DEBUG_NOTIFIERS=y
# CONFIG_DEBUG_CREDENTIALS is not set
CONFIG_ARCH_WANT_FRAME_POINTERS=y
CONFIG_FRAME_POINTER=y
CONFIG_RCU_TORTURE_TEST=y
CONFIG_RCU_TORTURE_TEST_RUNNABLE=y
CONFIG_RCU_TRACE=y
CONFIG_BACKTRACE_SELF_TEST=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
# CONFIG_LKDTM is not set
CONFIG_NOTIFIER_ERROR_INJECTION=y
CONFIG_PM_NOTIFIER_ERROR_INJECT=y
CONFIG_FAULT_INJECTION=y
# CONFIG_FAILSLAB is not set
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAIL_MAKE_REQUEST=y
CONFIG_FAIL_IO_TIMEOUT=y
CONFIG_FAIL_MMC_REQUEST=y
# CONFIG_FAULT_INJECTION_DEBUG_FS is not set
CONFIG_DEBUG_PAGEALLOC=y
CONFIG_WANT_PAGE_DEBUG_FLAGS=y
CONFIG_PAGE_GUARD=y
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
# CONFIG_BUILD_DOCSRC is not set
CONFIG_DMA_API_DEBUG=y
# CONFIG_ATOMIC64_SELFTEST is not set
# CONFIG_ASYNC_RAID6_TEST is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_KGDB_TESTS=y
CONFIG_KGDB_TESTS_ON_BOOT=y
CONFIG_KGDB_TESTS_BOOT_STRING="V1F100"
# CONFIG_KGDB_LOW_LEVEL_TRAP is not set
# CONFIG_KGDB_KDB is not set
CONFIG_HAVE_ARCH_KMEMCHECK=y
CONFIG_TEST_KSTRTOX=y
CONFIG_STRICT_DEVMEM=y
# CONFIG_X86_VERBOSE_BOOTUP is not set
# CONFIG_EARLY_PRINTK is not set
CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_X86_PTDUMP=y
# CONFIG_DEBUG_RODATA is not set
# CONFIG_DOUBLEFAULT is not set
# CONFIG_DEBUG_TLBFLUSH is not set
CONFIG_IOMMU_STRESS=y
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
CONFIG_IO_DELAY_TYPE_0X80=0
CONFIG_IO_DELAY_TYPE_0XED=1
CONFIG_IO_DELAY_TYPE_UDELAY=2
CONFIG_IO_DELAY_TYPE_NONE=3
# CONFIG_IO_DELAY_0X80 is not set
# CONFIG_IO_DELAY_0XED is not set
# CONFIG_IO_DELAY_UDELAY is not set
CONFIG_IO_DELAY_NONE=y
CONFIG_DEFAULT_IO_DELAY_TYPE=3
CONFIG_DEBUG_BOOT_PARAMS=y
# CONFIG_CPA_DEBUG is not set
CONFIG_OPTIMIZE_INLINING=y
# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set

#
# Security options
#
CONFIG_KEYS=y
CONFIG_TRUSTED_KEYS=y
CONFIG_ENCRYPTED_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY_DMESG_RESTRICT=y
CONFIG_SECURITY=y
CONFIG_SECURITYFS=y
CONFIG_SECURITY_NETWORK=y
# CONFIG_SECURITY_NETWORK_XFRM is not set
CONFIG_SECURITY_PATH=y
# CONFIG_INTEL_TXT is not set
CONFIG_SECURITY_SMACK=y
CONFIG_SECURITY_TOMOYO=y
CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY=2048
CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG=1024
# CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER is not set
CONFIG_SECURITY_TOMOYO_POLICY_LOADER="/sbin/tomoyo-init"
CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER="/sbin/init"
# CONFIG_SECURITY_APPARMOR is not set
CONFIG_SECURITY_YAMA=y
CONFIG_INTEGRITY=y
# CONFIG_INTEGRITY_SIGNATURE is not set
CONFIG_IMA=y
CONFIG_IMA_MEASURE_PCR_IDX=10
# CONFIG_EVM is not set
# CONFIG_DEFAULT_SECURITY_SMACK is not set
CONFIG_DEFAULT_SECURITY_TOMOYO=y
# CONFIG_DEFAULT_SECURITY_YAMA is not set
# CONFIG_DEFAULT_SECURITY_DAC is not set
CONFIG_DEFAULT_SECURITY="tomoyo"
CONFIG_XOR_BLOCKS=y
CONFIG_ASYNC_CORE=y
CONFIG_ASYNC_MEMCPY=y
CONFIG_ASYNC_XOR=y
CONFIG_ASYNC_PQ=y
CONFIG_ASYNC_RAID6_RECOV=y
CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA=y
CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA=y
CONFIG_CRYPTO=y

#
# Crypto core or helper
#
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_PCOMP2=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_USER=y
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
CONFIG_CRYPTO_GF128MUL=y
# CONFIG_CRYPTO_NULL is not set
CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_CRYPTO_CRYPTD=y
CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_ABLK_HELPER_X86=y

#
# Authenticated Encryption with Associated Data
#
# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_GCM is not set
CONFIG_CRYPTO_SEQIV=y

#
# Block modes
#
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CTR=y
# CONFIG_CRYPTO_CTS is not set
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_LRW=y
CONFIG_CRYPTO_PCBC=y
CONFIG_CRYPTO_XTS=y

#
# Hash modes
#
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_VMAC=y

#
# Digest
#
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_CRC32C_INTEL=y
CONFIG_CRYPTO_GHASH=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
CONFIG_CRYPTO_RMD128=y
CONFIG_CRYPTO_RMD160=y
# CONFIG_CRYPTO_RMD256 is not set
CONFIG_CRYPTO_RMD320=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=y
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_TGR192 is not set
CONFIG_CRYPTO_WP512=y

#
# Ciphers
#
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_AES_586=y
CONFIG_CRYPTO_AES_NI_INTEL=y
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_ARC4 is not set
CONFIG_CRYPTO_BLOWFISH=y
CONFIG_CRYPTO_BLOWFISH_COMMON=y
# CONFIG_CRYPTO_CAMELLIA is not set
CONFIG_CRYPTO_CAST5=y
CONFIG_CRYPTO_CAST6=y
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_DES_SPARC64=y
CONFIG_CRYPTO_FCRYPT=y
CONFIG_CRYPTO_KHAZAD=y
CONFIG_CRYPTO_SALSA20=y
CONFIG_CRYPTO_SALSA20_586=y
# CONFIG_CRYPTO_SEED is not set
# CONFIG_CRYPTO_SERPENT is not set
# CONFIG_CRYPTO_SERPENT_SSE2_586 is not set
CONFIG_CRYPTO_TEA=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_TWOFISH_COMMON=y
# CONFIG_CRYPTO_TWOFISH_586 is not set

#
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
# CONFIG_CRYPTO_ZLIB is not set
CONFIG_CRYPTO_LZO=y

#
# Random Number Generation
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_USER_API_HASH is not set
# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
# CONFIG_CRYPTO_HW is not set
CONFIG_HAVE_KVM=y
CONFIG_VIRTUALIZATION=y
# CONFIG_KVM is not set
# CONFIG_BINARY_PRINTF is not set

#
# Library routines
#
CONFIG_RAID6_PQ=y
CONFIG_BITREVERSE=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_IO=y
CONFIG_CRC_CCITT=y
CONFIG_CRC16=y
CONFIG_CRC_T10DIF=y
CONFIG_CRC_ITU_T=y
CONFIG_CRC32=y
CONFIG_CRC32_SELFTEST=y
# CONFIG_CRC32_SLICEBY8 is not set
# CONFIG_CRC32_SLICEBY4 is not set
CONFIG_CRC32_SARWATE=y
# CONFIG_CRC32_BIT is not set
# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=y
# CONFIG_CRC8 is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
# CONFIG_XZ_DEC is not set
# CONFIG_XZ_DEC_BCJ is not set
CONFIG_REED_SOLOMON=y
CONFIG_REED_SOLOMON_DEC16=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_CHECK_SIGNATURE=y
CONFIG_DQL=y
CONFIG_NLATTR=y
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
# CONFIG_AVERAGE is not set
CONFIG_CORDIC=y
# CONFIG_DDR is not set

^ permalink raw reply

* Re: [PATCH net] net: usbnet: fix softirq storm on suspend
From: Ming Lei @ 2012-09-05  0:30 UTC (permalink / raw)
  To: Bjørn Mork
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	Oliver Neukum
In-Reply-To: <877gsacbws.fsf-lbf33ChDnrE/G1V5fR+Y7Q@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 1673 bytes --]

On Tue, Sep 4, 2012 at 6:36 PM, Bjørn Mork <bjorn-yOkvZcmFvRU@public.gmane.org> wrote:
>
> I believe any Ericsson or Gobi modem would do, and most likely other USB
> networking devices too.
>
> I haven't explored the gadget.  Doesn't it support remote wakeup?  Well,

No.

> it doesn't really have to just for testing this.  You just have to fake
> the remote wakeup support, either in the gadget or in the device
> driver.  It doesn't matter whether it works or not.  The point is making
> the driver suspend the USB device while the network device is running.

The attachment patch is what I have been using to make it support remote
wakeup, and looks it works wrt. runtime PM.


>
>
>
> So the code trigging this seems to be
>
>
> static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb,
>                 struct sk_buff_head *list, enum skb_state state)
> {
>         unsigned long           flags;
>         enum skb_state          old_state;
>         struct skb_data *entry = (struct skb_data *) skb->cb;
>
>         spin_lock_irqsave(&list->lock, flags);
>         old_state = entry->state;
>         entry->state = state;
>         __skb_unlink(skb, list);
>         spin_unlock(&list->lock);
>         spin_lock(&dev->done.lock);
>         __skb_queue_tail(&dev->done, skb);
>         if (dev->done.qlen == 1)
>                 tasklet_schedule(&dev->bh);
>         spin_unlock_irqrestore(&dev->done.lock, flags);
>         return old_state;
> }
>
>
> Hmm, I should probably dump stack here as well.. Anyway, it's a start.

Maybe a debug message in defer_bh is enough, :-)


Thanks,
--
Ming Lei

[-- Attachment #2: usb-gadget-remote-wakeup.patch --]
[-- Type: application/octet-stream, Size: 1087 bytes --]

diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index a28f6ff..694f639 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -236,6 +236,7 @@ static int __init rndis_do_config(struct usb_configuration *c)
 		c->descriptors = otg_desc;
 		c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 	}
+	c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 
 	return rndis_bind_config(c, hostaddr);
 }
@@ -268,6 +269,7 @@ static int __init eth_do_config(struct usb_configuration *c)
 		c->descriptors = otg_desc;
 		c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 	}
+	c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 
 	if (use_eem)
 		return eem_bind_config(c);
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 47cf48b..197fcc0 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -497,6 +497,7 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
 	struct usb_ep		*in;
 	u16			cdc_filter;
 
+	usb_gadget_wakeup(dev->gadget);
 	spin_lock_irqsave(&dev->lock, flags);
 	if (dev->port_usb) {
 		in = dev->port_usb->in_ep;

^ permalink raw reply related

* [PATCH] ibmveth: Fix alignment of rx queue bug
From: Santiago Leon @ 2012-09-05  0:41 UTC (permalink / raw)
  To: netdev

This patch fixes a bug found by Nish Aravamudan 
(https://lkml.org/lkml/2012/5/15/220) where the driver is not following
the spec (it is not aligning the rx buffer on a 16-byte boundary) and the
hypervisor aborts the registration, making the device unusable. 

The fix follows BenH's recommendation (https://lkml.org/lkml/2012/7/20/461)
to replace the kmalloc+map for a single call to dma_alloc_coherent()
because that function always aligns to a 16-byte boundary.

The stable trees will run into this bug whenever the rx buffer kmalloc call
returns something not aligned on a 16-byte boundary.

Cc: <stable@vger.kernel.org>
Signed-off-by: Santiago Leon <santil@linux.vnet.ibm.com>
---
 ibmveth.c |   26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

--- a/drivers/net/ethernet/ibm/ibmveth.c	2012-07-09 16:00:53.000000000 -0400
+++ b/drivers/net/ethernet/ibm/ibmveth.c	2012-08-17 19:51:02.840000188 -0400
@@ -472,14 +472,9 @@ static void ibmveth_cleanup(struct ibmve
 	}
 
 	if (adapter->rx_queue.queue_addr != NULL) {
-		if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) {
-			dma_unmap_single(dev,
-					adapter->rx_queue.queue_dma,
-					adapter->rx_queue.queue_len,
-					DMA_BIDIRECTIONAL);
-			adapter->rx_queue.queue_dma = DMA_ERROR_CODE;
-		}
-		kfree(adapter->rx_queue.queue_addr);
+		dma_free_coherent(dev, adapter->rx_queue.queue_len,
+				  adapter->rx_queue.queue_addr,
+				  adapter->rx_queue.queue_dma);
 		adapter->rx_queue.queue_addr = NULL;
 	}
 
@@ -556,10 +551,13 @@ static int ibmveth_open(struct net_devic
 		goto err_out;
 	}
 
+	dev = &adapter->vdev->dev;
+
 	adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) *
 						rxq_entries;
-	adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len,
-						GFP_KERNEL);
+	adapter->rx_queue.queue_addr =
+	    dma_alloc_coherent(dev, adapter->rx_queue.queue_len,
+			       &adapter->rx_queue.queue_dma, GFP_KERNEL);
 
 	if (!adapter->rx_queue.queue_addr) {
 		netdev_err(netdev, "unable to allocate rx queue pages\n");
@@ -567,19 +565,13 @@ static int ibmveth_open(struct net_devic
 		goto err_out;
 	}
 
-	dev = &adapter->vdev->dev;
-
 	adapter->buffer_list_dma = dma_map_single(dev,
 			adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL);
 	adapter->filter_list_dma = dma_map_single(dev,
 			adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL);
-	adapter->rx_queue.queue_dma = dma_map_single(dev,
-			adapter->rx_queue.queue_addr,
-			adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL);
 
 	if ((dma_mapping_error(dev, adapter->buffer_list_dma)) ||
-	    (dma_mapping_error(dev, adapter->filter_list_dma)) ||
-	    (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) {
+	    (dma_mapping_error(dev, adapter->filter_list_dma))) {
 		netdev_err(netdev, "unable to map filter or buffer list "
 			   "pages\n");
 		rc = -ENOMEM;

^ permalink raw reply

* linux-next: manual merge of the net-next tree with the vfs tree
From: Stephen Rothwell @ 2012-09-05  2:02 UTC (permalink / raw)
  To: David Miller, netdev; +Cc: linux-next, linux-kernel, Masatake YAMATO, Al Viro

[-- Attachment #1: Type: text/plain, Size: 6029 bytes --]

Hi all,

Today's linux-next merge of the net-next tree got a conflict in
net/socket.c between commits f8a78429cc70 ("take descriptor handling from
sock_alloc_file() to callers") and 32b529f92ea7 ("unexport sock_map_fd(),
switch to sock_alloc_file()") from the vfs tree and commit 600e177920df
("net: Providing protocol type via system.sockprotoname xattr
of /proc/PID/fd entries") from the net-next tree.

I fixed it up (see below) and can carry the fix as necessary.  I also had
to add this merge fix patch:

From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Wed, 5 Sep 2012 11:52:06 +1000
Subject: [PATCH] net: cope with sock_alloc_file() API change

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 include/linux/net.h |    3 ++-
 net/9p/trans_fd.c   |    2 +-
 net/sctp/socket.c   |    2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/linux/net.h b/include/linux/net.h
index c8a9708..a3831f3 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -247,7 +247,8 @@ extern int   	     sock_sendmsg(struct socket *sock, struct msghdr *msg,
 				  size_t len);
 extern int	     sock_recvmsg(struct socket *sock, struct msghdr *msg,
 				  size_t size, int flags);
-extern struct file  *sock_alloc_file(struct socket *sock, int flags);
+extern struct file  *sock_alloc_file(struct socket *sock, int flags,
+				     const char *dname);
 extern struct socket *sockfd_lookup(int fd, int *err);
 extern struct socket *sock_from_file(struct file *file, int *err);
 #define		     sockfd_put(sock) fput(sock->file)
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index 8c4e0b5..1c8b557 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -801,7 +801,7 @@ static int p9_socket_open(struct p9_client *client, struct socket *csocket)
 		return -ENOMEM;
 
 	csocket->sk->sk_allocation = GFP_NOIO;
-	file = sock_alloc_file(csocket, 0);
+	file = sock_alloc_file(csocket, 0, NULL);
 	if (IS_ERR(file)) {
 		pr_err("%s (%d): failed to map fd\n",
 		       __func__, task_pid_nr(current));
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 5ba739e..59d16ea 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4313,7 +4313,7 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval
 		goto out;
 	}
 
-	newfile = sock_alloc_file(newsock, 0);
+	newfile = sock_alloc_file(newsock, 0, NULL);
 	if (unlikely(IS_ERR(newfile))) {
 		put_unused_fd(retval);
 		sock_release(newsock);
-- 
1.7.10.280.gaa39

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --cc net/socket.c
index 79170dc,977c0f4..0000000
--- a/net/socket.c
+++ b/net/socket.c
@@@ -346,15 -347,30 +347,23 @@@ static struct file_system_type sock_fs_
   *	but we take care of internal coherence yet.
   */
  
- struct file *sock_alloc_file(struct socket *sock, int flags)
 -static int sock_alloc_file(struct socket *sock, struct file **f, int flags,
 -			   const char *dname)
++struct file *sock_alloc_file(struct socket *sock, int flags,
++			     const char *dname)
  {
  	struct qstr name = { .name = "" };
  	struct path path;
  	struct file *file;
 -	int fd;
 -
 -	fd = get_unused_fd_flags(flags);
 -	if (unlikely(fd < 0))
 -		return fd;
  
+ 	if (dname) {
+ 		name.name = dname;
+ 		name.len = strlen(name.name);
+ 	} else if (sock->sk) {
+ 		name.name = sock->sk->sk_prot_creator->name;
+ 		name.len = strlen(name.name);
+ 	}
  	path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name);
 -	if (unlikely(!path.dentry)) {
 -		put_unused_fd(fd);
 -		return -ENOMEM;
 -	}
 +	if (unlikely(!path.dentry))
 +		return ERR_PTR(-ENOMEM);
  	path.mnt = mntget(sock_mnt);
  
  	d_instantiate(path.dentry, SOCK_INODE(sock));
@@@ -373,26 -390,22 +382,26 @@@
  	file->f_flags = O_RDWR | (flags & O_NONBLOCK);
  	file->f_pos = 0;
  	file->private_data = sock;
 -
 -	*f = file;
 -	return fd;
 +	return file;
  }
 +EXPORT_SYMBOL(sock_alloc_file);
  
 -int sock_map_fd(struct socket *sock, int flags)
 +static int sock_map_fd(struct socket *sock, int flags)
  {
  	struct file *newfile;
 -	int fd = sock_alloc_file(sock, &newfile, flags, NULL);
 +	int fd = get_unused_fd_flags(flags);
 +	if (unlikely(fd < 0))
 +		return fd;
  
- 	newfile = sock_alloc_file(sock, flags);
 -	if (likely(fd >= 0))
++	newfile = sock_alloc_file(sock, flags, NULL);
 +	if (likely(!IS_ERR(newfile))) {
  		fd_install(fd, newfile);
 +		return fd;
 +	}
  
 -	return fd;
 +	put_unused_fd(fd);
 +	return PTR_ERR(newfile);
  }
 -EXPORT_SYMBOL(sock_map_fd);
  
  struct socket *sock_from_file(struct file *file, int *err)
  {
@@@ -1395,27 -1471,12 +1467,27 @@@ SYSCALL_DEFINE4(socketpair, int, family
  		err = fd1;
  		goto out_release_both;
  	}
 -
 -	fd2 = sock_alloc_file(sock2, &newfile2, flags, NULL);
 +	fd2 = get_unused_fd_flags(flags);
  	if (unlikely(fd2 < 0)) {
  		err = fd2;
 +		put_unused_fd(fd1);
 +		goto out_release_both;
 +	}
 +
- 	newfile1 = sock_alloc_file(sock1, flags);
++	newfile1 = sock_alloc_file(sock1, flags, NULL);
 +	if (unlikely(IS_ERR(newfile1))) {
 +		err = PTR_ERR(newfile1);
 +		put_unused_fd(fd1);
 +		put_unused_fd(fd2);
 +		goto out_release_both;
 +	}
 +
- 	newfile2 = sock_alloc_file(sock2, flags);
++	newfile2 = sock_alloc_file(sock2, flags, NULL);
 +	if (IS_ERR(newfile2)) {
 +		err = PTR_ERR(newfile2);
  		fput(newfile1);
  		put_unused_fd(fd1);
 +		put_unused_fd(fd2);
  		sock_release(sock2);
  		goto out;
  	}
@@@ -1553,13 -1615,6 +1625,14 @@@ SYSCALL_DEFINE4(accept4, int, fd, struc
  		sock_release(newsock);
  		goto out_put;
  	}
- 	newfile = sock_alloc_file(newsock, flags);
++	newfile = sock_alloc_file(newsock, flags,
++				  sock->sk->sk_prot_creator->name);
 +	if (unlikely(IS_ERR(newfile))) {
 +		err = PTR_ERR(newfile);
 +		put_unused_fd(newfd);
 +		sock_release(newsock);
 +		goto out_put;
 +	}
  
  	err = security_socket_accept(sock, newsock);
  	if (err)

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply related

* Re: [PATCHv2] virtio-spec: virtio network device multiqueue support
From: Jason Wang @ 2012-09-05  3:34 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: netdev, kvm, virtualization
In-Reply-To: <20120903115526.GA3815@redhat.com>

On 09/03/2012 07:55 PM, Michael S. Tsirkin wrote:
> At Jason's request, I am trying to help finalize the spec for
> the new multiqueue feature.
>
> Changes from Jason's rfc:
> - reserved vq 3: this makes all rx vqs even and tx vqs odd, which
>    looks nicer to me.
> - documented packet steering, added a generalized steering programming
>    command. Current modes are single queue and host driven multiqueue,
>    but I envision support for guest driven multiqueue in the future.

For host driven, more thought in the long term. Maybe we could add more 
policy to choose the rxq such as hashing, round-robin and cpuid.
> - make default vqs unused when in mq mode - this wastes some memory
>    but makes it more efficient to switch between modes as
>    we can avoid this causing packet reordering.

Not sure whether or not this can really helps. Depending on the host 
scheduler, we may always see a disorder when we do the switching.
> Rusty, could you please take a look and comment?
> If this looks OK to everyone, we can proceed with finalizing the
> implementation.  This patch is against
> eb9fc84d0d3c46438aaab190e2401a9e5409a052 in virtio-spec git tree.
>
> -->
>
> virtio-spec: virtio network device multiqueue support
>
> Add multiqueue support to virtio network device.
> Add a new feature flag VIRTIO_NET_F_MULTIQUEUE for this feature, a new
> configuration field max_virtqueue_pairs to detect supported number of
> virtqueues as well as a new command VIRTIO_NET_CTRL_STEERING to program
> packet steering.
>
> Signed-off-by: Michael S. Tsirkin<mst@redhat.com>
>
> --
>
> diff --git a/virtio-spec.lyx b/virtio-spec.lyx
> index 7a073f4..583debc 100644
> --- a/virtio-spec.lyx
> +++ b/virtio-spec.lyx
> @@ -58,6 +58,7 @@
>   \html_be_strict false
>   \author -608949062 "Rusty Russell,,,"
>   \author 1531152142 "Paolo Bonzini,,,"
> +\author 1986246365 "Michael S. Tsirkin"
>   \end_header
>
>   \begin_body
> @@ -3896,6 +3897,37 @@ Only if VIRTIO_NET_F_CTRL_VQ set
>   \end_inset
>
>
> +\change_inserted 1986246365 1346663522
> + 3: reserved
> +\end_layout
> +
> +\begin_layout Description
> +
> +\change_inserted 1986246365 1346663550
> +4: receiveq1.
> + 5: transmitq1.
> + 6: receiveq2.
> + 7.
> + transmitq2.
> + ...
> + 2N+2:receivqN, 2N+3:transmitqN
> +\begin_inset Foot
> +status open
> +
> +\begin_layout Plain Layout
> +
> +\change_inserted 1986246365 1346663558
> +Only if VIRTIO_NET_F_CTRL_VQ set.
> + N is indicated by max_virtqueue_pairs field.
> +\change_unchanged
> +
> +\end_layout
> +
> +\end_inset
> +
> +
> +\change_unchanged
> +
>   \end_layout
>
>   \begin_layout Description
> @@ -4056,6 +4088,17 @@ VIRTIO_NET_F_CTRL_VLAN
>
>   \begin_layout Description
>   VIRTIO_NET_F_GUEST_ANNOUNCE(21) Guest can send gratuitous packets.
> +\change_inserted 1986246365 1346617842
> +
> +\end_layout
> +
> +\begin_layout Description
> +
> +\change_inserted 1986246365 1346618103
> +VIRTIO_NET_F_MULTIQUEUE(22) Device has multiple receive and transmission
> + queues.
> +\change_unchanged
> +
>   \end_layout
>
>   \end_deeper
> @@ -4068,11 +4111,45 @@ configuration
>   \begin_inset space ~
>   \end_inset
>
> -layout Two configuration fields are currently defined.
> +layout
> +\change_deleted 1986246365 1346671560
> +Two
> +\change_inserted 1986246365 1346671647
> +Six
> +\change_unchanged
> + configuration fields are currently defined.
>    The mac address field always exists (though is only valid if VIRTIO_NET_F_MAC
>    is set), and the status field only exists if VIRTIO_NET_F_STATUS is set.
>    Two read-only bits are currently defined for the status field: VIRTIO_NET_S_LIN
>   K_UP and VIRTIO_NET_S_ANNOUNCE.
> +
> +\change_inserted 1986246365 1346672138
> + The following four read-only fields only exists if VIRTIO_NET_F_MULTIQUEUE
> + is set.
> + The max_virtqueue_pairs field specifies the maximum number of each of transmit
> + and receive virtqueues that can used for multiqueue operation.

s/can/can be/
> + The following read-only fields:
> +\emph on
> +current_steering_rule
> +\emph default
> +,
> +\emph on
> +reserved
> +\emph default
> + and
> +\emph on
> +current_steering_param
> +\emph default
> + store the last successful VIRTIO_NET_CTRL_STEERING
> +\begin_inset CommandInset ref
> +LatexCommand ref
> +reference "sub:Transmit-Packet-Steering"
> +
> +\end_inset
> +
> + command executed by driver, for debugging.
> +
> +\change_unchanged
>
>   \begin_inset listings
>   inline false
> @@ -4105,6 +4182,40 @@ struct virtio_net_config {
>   \begin_layout Plain Layout
>
>       u16 status;
> +\change_inserted 1986246365 1346671221
> +
> +\end_layout
> +
> +\begin_layout Plain Layout
> +
> +\change_inserted 1986246365 1346671532
> +
> +    u16 max_virtqueue_pairs;
> +\end_layout
> +
> +\begin_layout Plain Layout
> +
> +\change_inserted 1986246365 1346671531
> +
> +    u8 current_steering_rule;
> +\change_unchanged
> +
> +\end_layout
> +
> +\begin_layout Plain Layout
> +
> +\change_inserted 1986246365 1346671499
> +
> +    u8 reserved;
> +\end_layout
> +
> +\begin_layout Plain Layout
> +
> +\change_inserted 1986246365 1346671530
> +
> +    u16 current_steering_param;
> +\change_unchanged
> +
>   \end_layout
>
>   \begin_layout Plain Layout
> @@ -4151,6 +4262,18 @@ physical
>   \begin_layout Enumerate
>   If the VIRTIO_NET_F_CTRL_VQ feature bit is negotiated, identify the control
>    virtqueue.
> +\change_inserted 1986246365 1346618052
> +
> +\end_layout
> +
> +\begin_layout Enumerate
> +
> +\change_inserted 1986246365 1346618175
> +If VIRTIO_NET_F_MULTIQUEUE feature bit is negotiated, identify the receive
> + and transmission queues that are going to be used in multiqueue mode.
> + Only queues that are going to be used need to be initialized.
> +\change_unchanged
> +
>   \end_layout
>
>   \begin_layout Enumerate
> @@ -4168,7 +4291,11 @@ status
>   \end_layout
>
>   \begin_layout Enumerate
> -The receive virtqueue should be filled with receive buffers.
> +The receive virtqueue
> +\change_inserted 1986246365 1346618180
> +(s)
> +\change_unchanged
> + should be filled with receive buffers.
>    This is described in detail below in
>   \begin_inset Quotes eld
>   \end_inset
> @@ -4516,6 +4643,201 @@ Note that the header will be two bytes longer for the VIRTIO_NET_F_MRG_RXBUF
>   \end_layout
>
>   \begin_layout Subsection*
> +
> +\change_inserted 1986246365 1346670975
> +\begin_inset CommandInset label
> +LatexCommand label
> +name "sub:Transmit-Packet-Steering"
> +
> +\end_inset
> +
> +Transmit Packet Steering
> +\end_layout
> +

Since this needs control vq, move this after the section of control vq?
> +\begin_layout Standard
> +
> +\change_inserted 1986246365 1346670592
> +When VIRTIO_NET_F_MULTIQUEUE feature bit is negotiated, guest can use any
> + of multiple configured transmit queues to transmit a given packet.
> + To avoid packet reordering by device (which gnerally leads to performance
> + degradation) driver should attempt to utilize the same transmit virtqueue
> + for all packets of a given transmit flow.
> + For bi-directional protocols (in practice, TCP), a given network connection
> + can utilize both transmit and receive queues.
> + For best performance, packets from a single connection should utilize the
> + paired transmit and receive queues from the same virtqueue pair; for example
> + both transmitqN and receiveqN.
> + This rule makes it possible to optimize processing on the device side,
> + but this is not a hard requirement: devices should function correctly even
> + when this rule is not followed.
> +\end_layout
> +
> +\begin_layout Standard
> +
> +\change_inserted 1986246365 1346670727
> +Driver selects an active steering rule using VIRTIO_NET_CTRL_STEERING command
> + (this controls both which virtqueue is selected for a given packet for
> + receive and notifies the device which virtqueues are about to be used for
> + transmit).
> +\end_layout
> +
> +\begin_layout Standard
> +

Not sure it's suitable to define the policy in the spec ( and even a not 
hard requirement ). An alternative is to just define some tools such as 
the queue number negotiation mechanism like modern card and just let the 
driver to choose the policy, this can give both flexibility and space 
for the future evolution of the device. E.g. we may have a guest 
controlled flow director in the future, we can have a seperate command 
to enable/disable it and a separate feature bits.
> +\change_inserted 1986246365 1346670594
> +This command accepts a single out argument in the following format:
> +\end_layout
> +
> +\begin_layout Standard
> +
> +\change_inserted 1986246365 1346670594
> +\begin_inset listings
> +inline false
> +status open
> +
> +\begin_layout Plain Layout
> +
> +\change_inserted 1986246365 1346670594
> +
> +#define VIRTIO_NET_CTRL_STEERING       4
> +\end_layout
> +
> +\begin_layout Plain Layout
> +
> +\change_inserted 1986246365 1346670594
> +
> +\end_layout
> +
> +\begin_layout Plain Layout
> +
> +\change_inserted 1986246365 1346670594
> +
> +struct virtio_net_ctrl_steering {
> +\end_layout
> +
> +\begin_layout Plain Layout
> +
> +\change_inserted 1986246365 1346671425
> +
> +	u8 current_steering_rule;
> +\end_layout
> +
> +\begin_layout Plain Layout
> +
> +\change_inserted 1986246365 1346670594
> +
> +    u8 reserved;
> +\end_layout
> +
> +\begin_layout Plain Layout
> +
> +\change_inserted 1986246365 1346671485
> +
> +	u16 current_steering_param;
> +\end_layout
> +
> +\begin_layout Plain Layout
> +
> +\change_inserted 1986246365 1346670594
> +
> +};
> +\end_layout
> +
> +\begin_layout Plain Layout
> +
> +\change_inserted 1986246365 1346670594
> +
> +#define VIRTIO_NET_CTRL_STEERING_SINGLE       0
> +\end_layout
> +
> +\begin_layout Plain Layout
> +
> +\change_inserted 1986246365 1346670594
> +
> +#define VIRTIO_NET_CTRL_STEERING_HOST  1
> +\end_layout
> +
> +\end_inset
> +
> +
> +\end_layout
> +
> +\begin_layout Standard
> +
> +\change_inserted 1986246365 1346671803
> +The field
> +\emph on
> +rule
> +\emph default
> + specifies the function used to select transmit virtqueue for a given packet;
> + the field
> +\emph on
> +param
> +\emph default
> + makes it possible to pass an extra parameter if appropriate.
> + When
> +\emph on
> +rule
> +\emph default
> + is set to VIRTIO_NET_CTRL_STEERING_SINGLE all packets are steered to the
> + default virtqueue transmitq (1); param is unused; this is the default.
> + When
> +\emph on
> +rule
> +\emph default
> + is set to VIRTIO_NET_CTRL_STEERING_HOST packets are steered by driver to
> + the first (
> +\emph on
> +param
> +\emph default
> ++1) multiqueue virtqueues transmitq1...transmitqN; the default transmitq is
> + unused.

It's driver that select the transmitq, does the device need to know 
about the transmit steering used in driver? defining the those 
transmission steering commands for the deivce looks useless. Maybe we'd 
better rename the subsection to "Packet Steering" and focus on the 
receive part?

> + Driver must have configured all these (
> +\emph on
> +param
> +\emph default
> ++1) virtqueues beforehand.
> + For best performance, driver should detects flow to virtqueue pair mapping
> + on receive and selects the transmit virtqueue from the same virtqueue pair.
> +\end_layout
> +
> +\begin_layout Standard
> +
> +\change_inserted 1986246365 1346670762
> +Supported steering rules can be added and removed in the future.
> + Driver should probe for supported rules by checking ack values of the command.
> +\end_layout
> +

What's the advantages of using this over feature bits?
> +\begin_layout Standard
> +
> +\change_inserted 1986246365 1346671315
> +When steering rule is modified, some packets can still be outstanding in
> + one or more of the virtqueues.
> + For transmit, device is recommended to complete processing of the transmit
> + queue(s) utilized by the original steering before processing any packets
> + delivered by the modified steering rule.
> +\end_layout
> +
> +\begin_layout Standard
> +
> +\change_inserted 1986246365 1346671412
> +For debugging, current steering rule can also be read from the configuration
> + space.
> +\end_layout
> +
> +\begin_layout Standard
> +
> +\change_inserted 1986246365 1346670762
> +See also receive steering description
> +\begin_inset CommandInset ref
> +LatexCommand ref
> +reference "sub:Receive-Packet-Steering"
> +
> +\end_inset
> +
> +.
> +\end_layout
> +
> +\begin_layout Subsection*
>   Packet Transmission Interrupt
>   \end_layout
>
> @@ -4988,8 +5310,24 @@ status open
>   The Guest needs to check VIRTIO_NET_S_ANNOUNCE bit in status field when
>    it notices the changes of device configuration.
>    The command VIRTIO_NET_CTRL_ANNOUNCE_ACK is used to indicate that driver
> - has recevied the notification and device would clear the VIRTIO_NET_S_ANNOUNCE
> - bit in the status filed after it received this command.
> + has rece
> +\change_inserted 1986246365 1346663932
> +i
> +\change_unchanged
> +v
> +\change_deleted 1986246365 1346663934
> +i
> +\change_unchanged
> +ed the notification and device would clear the VIRTIO_NET_S_ANNOUNCE bit
> + in the status fi
> +\change_inserted 1986246365 1346663942
> +e
> +\change_unchanged
> +l
> +\change_deleted 1986246365 1346663943
> +e
> +\change_unchanged
> +d after it received this command.
>   \end_layout
>
>   \begin_layout Standard
> @@ -5004,10 +5342,101 @@ Sending the gratuitous packets or marking there are pending gratuitous packets
>   \begin_layout Enumerate
>   Sending VIRTIO_NET_CTRL_ANNOUNCE_ACK command through control vq.
>
> +\change_deleted 1986246365 1346662247
> +
>   \end_layout
>
> -\begin_layout Enumerate
> +\begin_layout Subsection*
> +
> +\change_inserted 1986246365 1346670357
> +\begin_inset CommandInset label
> +LatexCommand label
> +name "sub:Receive-Packet-Steering"
> +
> +\end_inset
> +
> +Receive Packet Steering
> +\end_layout
> +
> +\begin_layout Standard
> +
> +\change_inserted 1986246365 1346671046
> +When VIRTIO_NET_F_MULTIQUEUE feature bit is negotiated, device can use any
> + of multiple configured receive queues to pass a given packet to driver.
> + Driver controls which virtqueue is selected in practice by configuring
> + packet steering rule using VIRTIO_NET_CTRL_STEERING command, as described
> + above
> +\begin_inset CommandInset ref
> +LatexCommand ref
> +reference "sub:Transmit-Packet-Steering"
> +
> +\end_inset
> +
>   .
> +\end_layout
> +
> +\begin_layout Standard
> +
> +\change_inserted 1986246365 1346671818
> +The field
> +\emph on
> +rule
> +\emph default
> + specifies the function used to select receive virtqueue for a given packet;
> + the field
> +\emph on
> +param
> +\emph default
> + makes it possible to pass an extra parameter if appropriate.
> + When
> +\emph on
> +rule
> +\emph default
> + is set to VIRTIO_NET_CTRL_STEERING_SINGLE all packets are steered to the
> + default virtqueue receveq (0); param is unused; this is the default.

A question here is whether or not we need to do the seamless switching 
between mq modes and sq modes. If we expect it happens rare, we could 
afforad some disordering by dropping this and just do the switching by 
resetting the device and negotiating the MULTIQUEUE bit or not on 
demand. This can simplify the implemention.
> + When
> +\emph on
> +rule
> +\emph default
> + is set to VIRTIO_NET_CTRL_STEERING_HOST packets are steered by host using
> + a device-specific steering function to the first (
> +\emph on
> +param
> +\emph default
> ++1) multiqueue virtqueues receiveq1...receiveqN; the default receiveq is unused.
> + Driver must have configured all these (
> +\emph on
> +param
> +\emph default
> ++1) virtqueues beforehand.
> + For best performance, driver is expected to detect flow to virtqueue pair
> + mapping on receive and select the transmit virtqueue from the same virtqueue
> + pair.
> +\end_layout
> +
> +\begin_layout Standard
> +
> +\change_inserted 1986246365 1346669564
> +Supported steering rules can be added and removed in the future.
> + Driver should probe for supported rules by checking ack values of the command.
> +\end_layout
> +
> +\begin_layout Standard
> +
> +\change_inserted 1986246365 1346671151
> +When steering rule is modified, some packets can still be outstanding in
> + one or more of the virtqueues.
> + For receive, driver is recommended to complete processing of the receive
> + queue(s) utilized by the original steering before processing any packets
> + delivered by the modified steering rule.
> +\end_layout
> +
> +\begin_layout Standard
> +
> +\change_deleted 1986246365 1346664095
> +.
> +
> +\change_unchanged
>
>   \end_layout
>

^ permalink raw reply

* Re: [PATCH] usbnet: drop unneeded check for NULL
From: Richard Cochran @ 2012-09-05  4:47 UTC (permalink / raw)
  To: David Miller; +Cc: oliver, netdev
In-Reply-To: <20120904.123740.1915830868205918256.davem@davemloft.net>

On Tue, Sep 04, 2012 at 12:37:40PM -0400, David Miller wrote:
> From: Oliver Neukum <oliver@neukum.org>
> Date: Tue, 04 Sep 2012 18:13:18 +0200
> 
> > If that check is ever needed and tx_fixup not needed, the driver will oops here.
> > The check is wrong in any case.
> 
> Right, we are dealing with two different things here.
> 
> Tree-wide there was a blind set of changes to protect skb_tx_timestamp()
> calls with a NULL skb check.
> 
> But in this specific case, it's completely unnecessary.
> 
> So Oliver's change is definitely correct and I will add it to net-next

Looking at git blame on usbnet.c we see ...

    23ba0799	if (skb)
    23ba0799		skb_tx_timestamp(skb);

and reading on ...

    commit 23ba07991dad5a96a024c1b45cb602eef5f83df8
    Author: Konstantin Khlebnikov <khlebnikov@openvz.org>
    Date:   Mon Nov 7 05:54:58 2011 +0000

    usbnet: fix oops in usbnet_start_xmit
    
    This patch fixes the bug added in commit v3.1-rc7-1055-gf9b491e
    SKB can be NULL at this point, at least for cdc-ncm.
    
    Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org>
    Acked-by: Richard Cochran <richardcochran@gmail.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>

and finally cdc-ncm.c reveals

static void cdc_ncm_txpath_bh(unsigned long param)
{
	struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)param;

	spin_lock_bh(&ctx->mtx);
	if (ctx->tx_timer_pending != 0) {
		ctx->tx_timer_pending--;
		cdc_ncm_tx_timeout_start(ctx);
		spin_unlock_bh(&ctx->mtx);
	} else if (ctx->netdev != NULL) {
		spin_unlock_bh(&ctx->mtx);
		netif_tx_lock_bh(ctx->netdev);
		usbnet_start_xmit(NULL, ctx->netdev);
----------------------------------^^^^
		netif_tx_unlock_bh(ctx->netdev);
	}
}

and so I think the problem that the test addresses is still present,
or am I missing something?

Thanks,
Richard

^ permalink raw reply

* Re: linux-next: manual merge of the net-next tree with the vfs tree
From: Masatake YAMATO @ 2012-09-05  4:55 UTC (permalink / raw)
  To: sfr; +Cc: davem, netdev, linux-next, linux-kernel, viro
In-Reply-To: <20120905120204.a8990185fb80f6b1b65bc6ea@canb.auug.org.au>

Hi,

How can I see source files applied your patch?
(I'm very new to kernel development.)

You patch looks like a patch for another patch.

Masatake YAMATO

> Hi all,
> 
> Today's linux-next merge of the net-next tree got a conflict in
> net/socket.c between commits f8a78429cc70 ("take descriptor handling from
> sock_alloc_file() to callers") and 32b529f92ea7 ("unexport sock_map_fd(),
> switch to sock_alloc_file()") from the vfs tree and commit 600e177920df
> ("net: Providing protocol type via system.sockprotoname xattr
> of /proc/PID/fd entries") from the net-next tree.
> 
> I fixed it up (see below) and can carry the fix as necessary.  I also had
> to add this merge fix patch:
> 
> From: Stephen Rothwell <sfr@canb.auug.org.au>
> Date: Wed, 5 Sep 2012 11:52:06 +1000
> Subject: [PATCH] net: cope with sock_alloc_file() API change
> 
> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
> ---
>  include/linux/net.h |    3 ++-
>  net/9p/trans_fd.c   |    2 +-
>  net/sctp/socket.c   |    2 +-
>  3 files changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/net.h b/include/linux/net.h
> index c8a9708..a3831f3 100644
> --- a/include/linux/net.h
> +++ b/include/linux/net.h
> @@ -247,7 +247,8 @@ extern int   	     sock_sendmsg(struct socket *sock, struct msghdr *msg,
>  				  size_t len);
>  extern int	     sock_recvmsg(struct socket *sock, struct msghdr *msg,
>  				  size_t size, int flags);
> -extern struct file  *sock_alloc_file(struct socket *sock, int flags);
> +extern struct file  *sock_alloc_file(struct socket *sock, int flags,
> +				     const char *dname);
>  extern struct socket *sockfd_lookup(int fd, int *err);
>  extern struct socket *sock_from_file(struct file *file, int *err);
>  #define		     sockfd_put(sock) fput(sock->file)
> diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
> index 8c4e0b5..1c8b557 100644
> --- a/net/9p/trans_fd.c
> +++ b/net/9p/trans_fd.c
> @@ -801,7 +801,7 @@ static int p9_socket_open(struct p9_client *client, struct socket *csocket)
>  		return -ENOMEM;
>  
>  	csocket->sk->sk_allocation = GFP_NOIO;
> -	file = sock_alloc_file(csocket, 0);
> +	file = sock_alloc_file(csocket, 0, NULL);
>  	if (IS_ERR(file)) {
>  		pr_err("%s (%d): failed to map fd\n",
>  		       __func__, task_pid_nr(current));
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index 5ba739e..59d16ea 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -4313,7 +4313,7 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval
>  		goto out;
>  	}
>  
> -	newfile = sock_alloc_file(newsock, 0);
> +	newfile = sock_alloc_file(newsock, 0, NULL);
>  	if (unlikely(IS_ERR(newfile))) {
>  		put_unused_fd(retval);
>  		sock_release(newsock);
> -- 
> 1.7.10.280.gaa39
> 
> -- 
> Cheers,
> Stephen Rothwell                    sfr@canb.auug.org.au
> 
> diff --cc net/socket.c
> index 79170dc,977c0f4..0000000
> --- a/net/socket.c
> +++ b/net/socket.c
> @@@ -346,15 -347,30 +347,23 @@@ static struct file_system_type sock_fs_
>    *	but we take care of internal coherence yet.
>    */
>   
> - struct file *sock_alloc_file(struct socket *sock, int flags)
>  -static int sock_alloc_file(struct socket *sock, struct file **f, int flags,
>  -			   const char *dname)
> ++struct file *sock_alloc_file(struct socket *sock, int flags,
> ++			     const char *dname)
>   {
>   	struct qstr name = { .name = "" };
>   	struct path path;
>   	struct file *file;
>  -	int fd;
>  -
>  -	fd = get_unused_fd_flags(flags);
>  -	if (unlikely(fd < 0))
>  -		return fd;
>   
> + 	if (dname) {
> + 		name.name = dname;
> + 		name.len = strlen(name.name);
> + 	} else if (sock->sk) {
> + 		name.name = sock->sk->sk_prot_creator->name;
> + 		name.len = strlen(name.name);
> + 	}
>   	path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name);
>  -	if (unlikely(!path.dentry)) {
>  -		put_unused_fd(fd);
>  -		return -ENOMEM;
>  -	}
>  +	if (unlikely(!path.dentry))
>  +		return ERR_PTR(-ENOMEM);
>   	path.mnt = mntget(sock_mnt);
>   
>   	d_instantiate(path.dentry, SOCK_INODE(sock));
> @@@ -373,26 -390,22 +382,26 @@@
>   	file->f_flags = O_RDWR | (flags & O_NONBLOCK);
>   	file->f_pos = 0;
>   	file->private_data = sock;
>  -
>  -	*f = file;
>  -	return fd;
>  +	return file;
>   }
>  +EXPORT_SYMBOL(sock_alloc_file);
>   
>  -int sock_map_fd(struct socket *sock, int flags)
>  +static int sock_map_fd(struct socket *sock, int flags)
>   {
>   	struct file *newfile;
>  -	int fd = sock_alloc_file(sock, &newfile, flags, NULL);
>  +	int fd = get_unused_fd_flags(flags);
>  +	if (unlikely(fd < 0))
>  +		return fd;
>   
> - 	newfile = sock_alloc_file(sock, flags);
>  -	if (likely(fd >= 0))
> ++	newfile = sock_alloc_file(sock, flags, NULL);
>  +	if (likely(!IS_ERR(newfile))) {
>   		fd_install(fd, newfile);
>  +		return fd;
>  +	}
>   
>  -	return fd;
>  +	put_unused_fd(fd);
>  +	return PTR_ERR(newfile);
>   }
>  -EXPORT_SYMBOL(sock_map_fd);
>   
>   struct socket *sock_from_file(struct file *file, int *err)
>   {
> @@@ -1395,27 -1471,12 +1467,27 @@@ SYSCALL_DEFINE4(socketpair, int, family
>   		err = fd1;
>   		goto out_release_both;
>   	}
>  -
>  -	fd2 = sock_alloc_file(sock2, &newfile2, flags, NULL);
>  +	fd2 = get_unused_fd_flags(flags);
>   	if (unlikely(fd2 < 0)) {
>   		err = fd2;
>  +		put_unused_fd(fd1);
>  +		goto out_release_both;
>  +	}
>  +
> - 	newfile1 = sock_alloc_file(sock1, flags);
> ++	newfile1 = sock_alloc_file(sock1, flags, NULL);
>  +	if (unlikely(IS_ERR(newfile1))) {
>  +		err = PTR_ERR(newfile1);
>  +		put_unused_fd(fd1);
>  +		put_unused_fd(fd2);
>  +		goto out_release_both;
>  +	}
>  +
> - 	newfile2 = sock_alloc_file(sock2, flags);
> ++	newfile2 = sock_alloc_file(sock2, flags, NULL);
>  +	if (IS_ERR(newfile2)) {
>  +		err = PTR_ERR(newfile2);
>   		fput(newfile1);
>   		put_unused_fd(fd1);
>  +		put_unused_fd(fd2);
>   		sock_release(sock2);
>   		goto out;
>   	}
> @@@ -1553,13 -1615,6 +1625,14 @@@ SYSCALL_DEFINE4(accept4, int, fd, struc
>   		sock_release(newsock);
>   		goto out_put;
>   	}
> - 	newfile = sock_alloc_file(newsock, flags);
> ++	newfile = sock_alloc_file(newsock, flags,
> ++				  sock->sk->sk_prot_creator->name);
>  +	if (unlikely(IS_ERR(newfile))) {
>  +		err = PTR_ERR(newfile);
>  +		put_unused_fd(newfd);
>  +		sock_release(newsock);
>  +		goto out_put;
>  +	}
>   
>   	err = security_socket_accept(sock, newsock);
>   	if (err)

^ permalink raw reply

* Re: [PATCH] userns: Add basic quota support v4
From: Eric W. Biederman @ 2012-09-05  5:20 UTC (permalink / raw)
  To: Dave Chinner
  Cc: Jan Kara, linux-kernel, netdev, linux-fsdevel, Serge E. Hallyn,
	David Miller, Steven Whitehouse, Mark Fasheh, Joel Becker,
	Ben Myers, Alex Elder, Dmitry Monakhov, Abhijith Das
In-Reply-To: <20120831011758.GH15292@dastard>



Dave Chinner <david@fromorbit.com> writes:

> On Wed, Aug 29, 2012 at 02:31:26AM -0700, Eric W. Biederman wrote:
>> 
>> Dave thanks for taking the time to take a detailed look at this code.
>> 
>> Dave Chinner <david@fromorbit.com> writes:
>> 
>> > On Tue, Aug 28, 2012 at 12:09:56PM -0700, Eric W. Biederman wrote:



>> > How did you test that this all works?
>> 
>> By making it a compile error if you get a conversion wrong and making it
>> a rule not to make any logic changes.
>>
>> That combined with code review
>> and running the code a bit to make certain I did not horribly mess up.
>
> But no actual regression testing. You're messing with code that I
> will have to triage when it goes wrong for a user, so IMO your code
> has to pass the same bar as the code I write has to pass for review
> - please regression test your code and write new regression tests
> for new functionality.

I like the idea of regression tests.  In practice and also with xfstests
I find that I spend lots of time debugging and fixing and improving
tests and at the end of the day I find regression tests tell me
very little.

But I did figure I should give them a try since I have a rather
substantial xfs patch in my queue.

I added tests 111 and 232 to the expunged file because the don't
run to completion.

ltp/rwtest.sh needs to be run with #!/bin/bash instead of #!/bin/sh as
it contains serveral bashisms.

You need to have gawk installed instead of mawk because of a non-posix
call to asort somewhere in the test framework.

On my branch userns-always-map-user-v53 or on v3.6-rc1+
xfs: check for possible overflow in xfs_ioc_trim
xfs: unlock the AGI buffer when looping in xfs_dialloc
xfs: fix uninitialised variable in xfs_rtbuf_get()

When I run ./check in the from xfstests I get

Tue Sep  4 05:06:12 PDT 2012
    001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018
    019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036
    037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054
    055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072
    073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090
    091 092 093 094 095 096 097 098 099 100 101 102 103 104 105 106 107 108
    109 110 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
    128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
    146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
    164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
    182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
    200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
    218 219 220 221 222 223 224 225 226 227 228 229 230 231 233 234 235 236
    237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
    255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
    273 274 275 276 277 278 279 280 281 282 283 284 285 286
Not run:2
Failures: 018 081 082 106 107 136 167 171 206 219 229 234 250 280
Failed 14 of 165 tests

But since the results came back the same either way I think the tests
told me all they can.  The 14 failed tests and 1 bug don't seem to say
good things about xfs in general though.

Eric

^ permalink raw reply

* Re: [PATCHv2] virtio-spec: virtio network device multiqueue support
From: Michael S. Tsirkin @ 2012-09-05  5:34 UTC (permalink / raw)
  To: Jason Wang; +Cc: netdev, kvm, virtualization
In-Reply-To: <5046C837.7040609@redhat.com>

On Wed, Sep 05, 2012 at 11:34:15AM +0800, Jason Wang wrote:
> On 09/03/2012 07:55 PM, Michael S. Tsirkin wrote:
> >At Jason's request, I am trying to help finalize the spec for
> >the new multiqueue feature.
> >
> >Changes from Jason's rfc:
> >- reserved vq 3: this makes all rx vqs even and tx vqs odd, which
> >   looks nicer to me.
> >- documented packet steering, added a generalized steering programming
> >   command. Current modes are single queue and host driven multiqueue,
> >   but I envision support for guest driven multiqueue in the future.
> 
> For host driven, more thought in the long term. Maybe we could add
> more policy to choose the rxq such as hashing, round-robin and
> cpuid.

As we discussed off-list, different guests may need wildly
different strategies. For example different queues for
different qos priorities might make a lot of sense.
So for now I'll remove the host-driven option and
add _GUEST (or maybe better name is _RX_FOLLOWS_TX)
rule which records the queue number on packet transmit and
uses that on receive.

> >- make default vqs unused when in mq mode - this wastes some memory
> >   but makes it more efficient to switch between modes as
> >   we can avoid this causing packet reordering.
> 
> Not sure whether or not this can really helps. Depending on the host
> scheduler, we may always see a disorder when we do the switching.

Since guest handles one queue at a time during switch,
won't this mean host reorders packets even with a single queue?

> >Rusty, could you please take a look and comment?
> >If this looks OK to everyone, we can proceed with finalizing the
> >implementation.  This patch is against
> >eb9fc84d0d3c46438aaab190e2401a9e5409a052 in virtio-spec git tree.
> >
> >-->
> >
> >virtio-spec: virtio network device multiqueue support
> >
> >Add multiqueue support to virtio network device.
> >Add a new feature flag VIRTIO_NET_F_MULTIQUEUE for this feature, a new
> >configuration field max_virtqueue_pairs to detect supported number of
> >virtqueues as well as a new command VIRTIO_NET_CTRL_STEERING to program
> >packet steering.
> >
> >Signed-off-by: Michael S. Tsirkin<mst@redhat.com>
> >
> >--
> >
> >diff --git a/virtio-spec.lyx b/virtio-spec.lyx
> >index 7a073f4..583debc 100644
> >--- a/virtio-spec.lyx
> >+++ b/virtio-spec.lyx
> >@@ -58,6 +58,7 @@
> >  \html_be_strict false
> >  \author -608949062 "Rusty Russell,,,"
> >  \author 1531152142 "Paolo Bonzini,,,"
> >+\author 1986246365 "Michael S. Tsirkin"
> >  \end_header
> >
> >  \begin_body
> >@@ -3896,6 +3897,37 @@ Only if VIRTIO_NET_F_CTRL_VQ set
> >  \end_inset
> >
> >
> >+\change_inserted 1986246365 1346663522
> >+ 3: reserved
> >+\end_layout
> >+
> >+\begin_layout Description
> >+
> >+\change_inserted 1986246365 1346663550
> >+4: receiveq1.
> >+ 5: transmitq1.
> >+ 6: receiveq2.
> >+ 7.
> >+ transmitq2.
> >+ ...
> >+ 2N+2:receivqN, 2N+3:transmitqN
> >+\begin_inset Foot
> >+status open
> >+
> >+\begin_layout Plain Layout
> >+
> >+\change_inserted 1986246365 1346663558
> >+Only if VIRTIO_NET_F_CTRL_VQ set.
> >+ N is indicated by max_virtqueue_pairs field.
> >+\change_unchanged
> >+
> >+\end_layout
> >+
> >+\end_inset
> >+
> >+
> >+\change_unchanged
> >+
> >  \end_layout
> >
> >  \begin_layout Description
> >@@ -4056,6 +4088,17 @@ VIRTIO_NET_F_CTRL_VLAN
> >
> >  \begin_layout Description
> >  VIRTIO_NET_F_GUEST_ANNOUNCE(21) Guest can send gratuitous packets.
> >+\change_inserted 1986246365 1346617842
> >+
> >+\end_layout
> >+
> >+\begin_layout Description
> >+
> >+\change_inserted 1986246365 1346618103
> >+VIRTIO_NET_F_MULTIQUEUE(22) Device has multiple receive and transmission
> >+ queues.
> >+\change_unchanged
> >+
> >  \end_layout
> >
> >  \end_deeper
> >@@ -4068,11 +4111,45 @@ configuration
> >  \begin_inset space ~
> >  \end_inset
> >
> >-layout Two configuration fields are currently defined.
> >+layout
> >+\change_deleted 1986246365 1346671560
> >+Two
> >+\change_inserted 1986246365 1346671647
> >+Six
> >+\change_unchanged
> >+ configuration fields are currently defined.
> >   The mac address field always exists (though is only valid if VIRTIO_NET_F_MAC
> >   is set), and the status field only exists if VIRTIO_NET_F_STATUS is set.
> >   Two read-only bits are currently defined for the status field: VIRTIO_NET_S_LIN
> >  K_UP and VIRTIO_NET_S_ANNOUNCE.
> >+
> >+\change_inserted 1986246365 1346672138
> >+ The following four read-only fields only exists if VIRTIO_NET_F_MULTIQUEUE
> >+ is set.
> >+ The max_virtqueue_pairs field specifies the maximum number of each of transmit
> >+ and receive virtqueues that can used for multiqueue operation.
> 
> s/can/can be/
> >+ The following read-only fields:
> >+\emph on
> >+current_steering_rule
> >+\emph default
> >+,
> >+\emph on
> >+reserved
> >+\emph default
> >+ and
> >+\emph on
> >+current_steering_param
> >+\emph default
> >+ store the last successful VIRTIO_NET_CTRL_STEERING
> >+\begin_inset CommandInset ref
> >+LatexCommand ref
> >+reference "sub:Transmit-Packet-Steering"
> >+
> >+\end_inset
> >+
> >+ command executed by driver, for debugging.
> >+
> >+\change_unchanged
> >
> >  \begin_inset listings
> >  inline false
> >@@ -4105,6 +4182,40 @@ struct virtio_net_config {
> >  \begin_layout Plain Layout
> >
> >      u16 status;
> >+\change_inserted 1986246365 1346671221
> >+
> >+\end_layout
> >+
> >+\begin_layout Plain Layout
> >+
> >+\change_inserted 1986246365 1346671532
> >+
> >+    u16 max_virtqueue_pairs;
> >+\end_layout
> >+
> >+\begin_layout Plain Layout
> >+
> >+\change_inserted 1986246365 1346671531
> >+
> >+    u8 current_steering_rule;
> >+\change_unchanged
> >+
> >+\end_layout
> >+
> >+\begin_layout Plain Layout
> >+
> >+\change_inserted 1986246365 1346671499
> >+
> >+    u8 reserved;
> >+\end_layout
> >+
> >+\begin_layout Plain Layout
> >+
> >+\change_inserted 1986246365 1346671530
> >+
> >+    u16 current_steering_param;
> >+\change_unchanged
> >+
> >  \end_layout
> >
> >  \begin_layout Plain Layout
> >@@ -4151,6 +4262,18 @@ physical
> >  \begin_layout Enumerate
> >  If the VIRTIO_NET_F_CTRL_VQ feature bit is negotiated, identify the control
> >   virtqueue.
> >+\change_inserted 1986246365 1346618052
> >+
> >+\end_layout
> >+
> >+\begin_layout Enumerate
> >+
> >+\change_inserted 1986246365 1346618175
> >+If VIRTIO_NET_F_MULTIQUEUE feature bit is negotiated, identify the receive
> >+ and transmission queues that are going to be used in multiqueue mode.
> >+ Only queues that are going to be used need to be initialized.
> >+\change_unchanged
> >+
> >  \end_layout
> >
> >  \begin_layout Enumerate
> >@@ -4168,7 +4291,11 @@ status
> >  \end_layout
> >
> >  \begin_layout Enumerate
> >-The receive virtqueue should be filled with receive buffers.
> >+The receive virtqueue
> >+\change_inserted 1986246365 1346618180
> >+(s)
> >+\change_unchanged
> >+ should be filled with receive buffers.
> >   This is described in detail below in
> >  \begin_inset Quotes eld
> >  \end_inset
> >@@ -4516,6 +4643,201 @@ Note that the header will be two bytes longer for the VIRTIO_NET_F_MRG_RXBUF
> >  \end_layout
> >
> >  \begin_layout Subsection*
> >+
> >+\change_inserted 1986246365 1346670975
> >+\begin_inset CommandInset label
> >+LatexCommand label
> >+name "sub:Transmit-Packet-Steering"
> >+
> >+\end_inset
> >+
> >+Transmit Packet Steering
> >+\end_layout
> >+
> 
> Since this needs control vq, move this after the section of control vq?

I don't mind but this is also transmit related.

> >+\begin_layout Standard
> >+
> >+\change_inserted 1986246365 1346670592
> >+When VIRTIO_NET_F_MULTIQUEUE feature bit is negotiated, guest can use any
> >+ of multiple configured transmit queues to transmit a given packet.
> >+ To avoid packet reordering by device (which gnerally leads to performance
> >+ degradation) driver should attempt to utilize the same transmit virtqueue
> >+ for all packets of a given transmit flow.
> >+ For bi-directional protocols (in practice, TCP), a given network connection
> >+ can utilize both transmit and receive queues.
> >+ For best performance, packets from a single connection should utilize the
> >+ paired transmit and receive queues from the same virtqueue pair; for example
> >+ both transmitqN and receiveqN.
> >+ This rule makes it possible to optimize processing on the device side,
> >+ but this is not a hard requirement: devices should function correctly even
> >+ when this rule is not followed.
> >+\end_layout
> >+
> >+\begin_layout Standard
> >+
> >+\change_inserted 1986246365 1346670727
> >+Driver selects an active steering rule using VIRTIO_NET_CTRL_STEERING command
> >+ (this controls both which virtqueue is selected for a given packet for
> >+ receive and notifies the device which virtqueues are about to be used for
> >+ transmit).
> >+\end_layout
> >+
> >+\begin_layout Standard
> >+
> 
> Not sure it's suitable to define the policy in the spec ( and even a
> not hard requirement ). An alternative is to just define some tools
> such as the queue number negotiation mechanism like modern card and
> just let the driver to choose the policy, this can give both
> flexibility and space for the future evolution of the device. E.g.
> we may have a guest controlled flow director in the future, we can
> have a seperate command to enable/disable it and a separate feature
> bits.

Problem with such approaches is, if we make them very generic they
will be slow (interpreter) or hard to implement (jit compiler).
I think rx follows tx above solves this neatly without
a lot of complexity.


> >+\change_inserted 1986246365 1346670594
> >+This command accepts a single out argument in the following format:
> >+\end_layout
> >+
> >+\begin_layout Standard
> >+
> >+\change_inserted 1986246365 1346670594
> >+\begin_inset listings
> >+inline false
> >+status open
> >+
> >+\begin_layout Plain Layout
> >+
> >+\change_inserted 1986246365 1346670594
> >+
> >+#define VIRTIO_NET_CTRL_STEERING       4
> >+\end_layout
> >+
> >+\begin_layout Plain Layout
> >+
> >+\change_inserted 1986246365 1346670594
> >+
> >+\end_layout
> >+
> >+\begin_layout Plain Layout
> >+
> >+\change_inserted 1986246365 1346670594
> >+
> >+struct virtio_net_ctrl_steering {
> >+\end_layout
> >+
> >+\begin_layout Plain Layout
> >+
> >+\change_inserted 1986246365 1346671425
> >+
> >+	u8 current_steering_rule;
> >+\end_layout
> >+
> >+\begin_layout Plain Layout
> >+
> >+\change_inserted 1986246365 1346670594
> >+
> >+    u8 reserved;
> >+\end_layout
> >+
> >+\begin_layout Plain Layout
> >+
> >+\change_inserted 1986246365 1346671485
> >+
> >+	u16 current_steering_param;
> >+\end_layout
> >+
> >+\begin_layout Plain Layout
> >+
> >+\change_inserted 1986246365 1346670594
> >+
> >+};
> >+\end_layout
> >+
> >+\begin_layout Plain Layout
> >+
> >+\change_inserted 1986246365 1346670594
> >+
> >+#define VIRTIO_NET_CTRL_STEERING_SINGLE       0
> >+\end_layout
> >+
> >+\begin_layout Plain Layout
> >+
> >+\change_inserted 1986246365 1346670594
> >+
> >+#define VIRTIO_NET_CTRL_STEERING_HOST  1
> >+\end_layout
> >+
> >+\end_inset
> >+
> >+
> >+\end_layout
> >+
> >+\begin_layout Standard
> >+
> >+\change_inserted 1986246365 1346671803
> >+The field
> >+\emph on
> >+rule
> >+\emph default
> >+ specifies the function used to select transmit virtqueue for a given packet;
> >+ the field
> >+\emph on
> >+param
> >+\emph default
> >+ makes it possible to pass an extra parameter if appropriate.
> >+ When
> >+\emph on
> >+rule
> >+\emph default
> >+ is set to VIRTIO_NET_CTRL_STEERING_SINGLE all packets are steered to the
> >+ default virtqueue transmitq (1); param is unused; this is the default.
> >+ When
> >+\emph on
> >+rule
> >+\emph default
> >+ is set to VIRTIO_NET_CTRL_STEERING_HOST packets are steered by driver to
> >+ the first (
> >+\emph on
> >+param
> >+\emph default
> >++1) multiqueue virtqueues transmitq1...transmitqN; the default transmitq is
> >+ unused.
> 
> It's driver that select the transmitq, does the device need to know
> about the transmit steering used in driver? defining the those
> transmission steering commands for the deivce looks useless. Maybe
> we'd better rename the subsection to "Packet Steering" and focus on
> the receive part?

Fow rx follows tx device needs to know how many tx queues
will be used.
Also I think it's good to be explicit and write up what
we expect driver to do rather than leave it to
drivers to interpret the spec any way they like.

> >+ Driver must have configured all these (
> >+\emph on
> >+param
> >+\emph default
> >++1) virtqueues beforehand.
> >+ For best performance, driver should detects flow to virtqueue pair mapping
> >+ on receive and selects the transmit virtqueue from the same virtqueue pair.
> >+\end_layout
> >+
> >+\begin_layout Standard
> >+
> >+\change_inserted 1986246365 1346670762
> >+Supported steering rules can be added and removed in the future.
> >+ Driver should probe for supported rules by checking ack values of the command.
> >+\end_layout
> >+
> 
> What's the advantages of using this over feature bits?

Feature bits are negotiated at startup. Experience shows
there might be no ideal steering rule for all workloads
so switching them at runtime is needed.


> >+\begin_layout Standard
> >+
> >+\change_inserted 1986246365 1346671315
> >+When steering rule is modified, some packets can still be outstanding in
> >+ one or more of the virtqueues.
> >+ For transmit, device is recommended to complete processing of the transmit
> >+ queue(s) utilized by the original steering before processing any packets
> >+ delivered by the modified steering rule.
> >+\end_layout
> >+
> >+\begin_layout Standard
> >+
> >+\change_inserted 1986246365 1346671412
> >+For debugging, current steering rule can also be read from the configuration
> >+ space.
> >+\end_layout
> >+
> >+\begin_layout Standard
> >+
> >+\change_inserted 1986246365 1346670762
> >+See also receive steering description
> >+\begin_inset CommandInset ref
> >+LatexCommand ref
> >+reference "sub:Receive-Packet-Steering"
> >+
> >+\end_inset
> >+
> >+.
> >+\end_layout
> >+
> >+\begin_layout Subsection*
> >  Packet Transmission Interrupt
> >  \end_layout
> >
> >@@ -4988,8 +5310,24 @@ status open
> >  The Guest needs to check VIRTIO_NET_S_ANNOUNCE bit in status field when
> >   it notices the changes of device configuration.
> >   The command VIRTIO_NET_CTRL_ANNOUNCE_ACK is used to indicate that driver
> >- has recevied the notification and device would clear the VIRTIO_NET_S_ANNOUNCE
> >- bit in the status filed after it received this command.
> >+ has rece
> >+\change_inserted 1986246365 1346663932
> >+i
> >+\change_unchanged
> >+v
> >+\change_deleted 1986246365 1346663934
> >+i
> >+\change_unchanged
> >+ed the notification and device would clear the VIRTIO_NET_S_ANNOUNCE bit
> >+ in the status fi
> >+\change_inserted 1986246365 1346663942
> >+e
> >+\change_unchanged
> >+l
> >+\change_deleted 1986246365 1346663943
> >+e
> >+\change_unchanged
> >+d after it received this command.
> >  \end_layout
> >
> >  \begin_layout Standard
> >@@ -5004,10 +5342,101 @@ Sending the gratuitous packets or marking there are pending gratuitous packets
> >  \begin_layout Enumerate
> >  Sending VIRTIO_NET_CTRL_ANNOUNCE_ACK command through control vq.
> >
> >+\change_deleted 1986246365 1346662247
> >+
> >  \end_layout
> >
> >-\begin_layout Enumerate
> >+\begin_layout Subsection*
> >+
> >+\change_inserted 1986246365 1346670357
> >+\begin_inset CommandInset label
> >+LatexCommand label
> >+name "sub:Receive-Packet-Steering"
> >+
> >+\end_inset
> >+
> >+Receive Packet Steering
> >+\end_layout
> >+
> >+\begin_layout Standard
> >+
> >+\change_inserted 1986246365 1346671046
> >+When VIRTIO_NET_F_MULTIQUEUE feature bit is negotiated, device can use any
> >+ of multiple configured receive queues to pass a given packet to driver.
> >+ Driver controls which virtqueue is selected in practice by configuring
> >+ packet steering rule using VIRTIO_NET_CTRL_STEERING command, as described
> >+ above
> >+\begin_inset CommandInset ref
> >+LatexCommand ref
> >+reference "sub:Transmit-Packet-Steering"
> >+
> >+\end_inset
> >+
> >  .
> >+\end_layout
> >+
> >+\begin_layout Standard
> >+
> >+\change_inserted 1986246365 1346671818
> >+The field
> >+\emph on
> >+rule
> >+\emph default
> >+ specifies the function used to select receive virtqueue for a given packet;
> >+ the field
> >+\emph on
> >+param
> >+\emph default
> >+ makes it possible to pass an extra parameter if appropriate.
> >+ When
> >+\emph on
> >+rule
> >+\emph default
> >+ is set to VIRTIO_NET_CTRL_STEERING_SINGLE all packets are steered to the
> >+ default virtqueue receveq (0); param is unused; this is the default.
> 
> A question here is whether or not we need to do the seamless
> switching between mq modes and sq modes. If we expect it happens
> rare, we could afforad some disordering by dropping this and just do
> the switching by resetting the device and negotiating the MULTIQUEUE
> bit or not on demand.

So far your own performance results show there is no
ideal mode. And to me, this makes a lot of sense.
If you reset on switch this is very slow, so this basically means you
will forever rely on guest admin to know what the right thing to do is.
I agree it's a sensible thing to do in v1 but long term
an adaptive strategy requires that mode switch is lightweight.

> This can simplify the implemention.

It only seems like that. That's much more work for a driver to do, and
lots of races to avoid.  Just using vqs negotiated at startup is exactly
what all drivers currently do - it is much easier to do correctly.

> >+ When
> >+\emph on
> >+rule
> >+\emph default
> >+ is set to VIRTIO_NET_CTRL_STEERING_HOST packets are steered by host using
> >+ a device-specific steering function to the first (
> >+\emph on
> >+param
> >+\emph default
> >++1) multiqueue virtqueues receiveq1...receiveqN; the default receiveq is unused.
> >+ Driver must have configured all these (
> >+\emph on
> >+param
> >+\emph default
> >++1) virtqueues beforehand.
> >+ For best performance, driver is expected to detect flow to virtqueue pair
> >+ mapping on receive and select the transmit virtqueue from the same virtqueue
> >+ pair.
> >+\end_layout
> >+
> >+\begin_layout Standard
> >+
> >+\change_inserted 1986246365 1346669564
> >+Supported steering rules can be added and removed in the future.
> >+ Driver should probe for supported rules by checking ack values of the command.
> >+\end_layout
> >+
> >+\begin_layout Standard
> >+
> >+\change_inserted 1986246365 1346671151
> >+When steering rule is modified, some packets can still be outstanding in
> >+ one or more of the virtqueues.
> >+ For receive, driver is recommended to complete processing of the receive
> >+ queue(s) utilized by the original steering before processing any packets
> >+ delivered by the modified steering rule.
> >+\end_layout
> >+
> >+\begin_layout Standard
> >+
> >+\change_deleted 1986246365 1346664095
> >+.
> >+
> >+\change_unchanged
> >
> >  \end_layout
> >

^ 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