Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 2/4] bnx2x: Use dma_alloc_coherent() semantics for ILT memory allocation
From: Vladislav Zolotarov @ 2010-12-08 11:43 UTC (permalink / raw)
  To: Dave Miller; +Cc: netdev list, Eilon Greenstein

Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/bnx2x/bnx2x.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index cfc25cf..abbdf6d 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -1336,7 +1336,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 
 #define BNX2X_ILT_ZALLOC(x, y, size) \
 	do { \
-		x = pci_alloc_consistent(bp->pdev, size, y); \
+		x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \
 		if (x) \
 			memset(x, 0, size); \
 	} while (0)
@@ -1344,7 +1344,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 #define BNX2X_ILT_FREE(x, y, size) \
 	do { \
 		if (x) { \
-			pci_free_consistent(bp->pdev, size, x, y); \
+			dma_free_coherent(&bp->pdev->dev, size, x, y); \
 			x = NULL; \
 			y = 0; \
 		} \
-- 
1.7.0.4





^ permalink raw reply related

* [PATCH net-next 3/4] bnx2x: Fixed a compilation warning
From: Vladislav Zolotarov @ 2010-12-08 11:43 UTC (permalink / raw)
  To: Dave Miller; +Cc: netdev list, Eilon Greenstein

bnx2x_src_init_t2() is used only when BCM_CNIC is defined.
So, to avoid a compilation warning, we won't define it unless
BCM_CNIC is defined.

Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/bnx2x/bnx2x_init_ops.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h
index a306b0e..66df29f 100644
--- a/drivers/net/bnx2x/bnx2x_init_ops.h
+++ b/drivers/net/bnx2x/bnx2x_init_ops.h
@@ -838,7 +838,7 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count,
 /****************************************************************************
 * SRC initializations
 ****************************************************************************/
-
+#ifdef BCM_CNIC
 /* called during init func stage */
 static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2,
 			      dma_addr_t t2_mapping, int src_cid_count)
@@ -862,5 +862,5 @@ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2,
 		    U64_HI((u64)t2_mapping +
 			   (src_cid_count-1) * sizeof(struct src_ent)));
 }
-
+#endif
 #endif /* BNX2X_INIT_OPS_H */
-- 
1.7.0.4





^ permalink raw reply related

* [PATCH net-next 4/4] bnx2x: Update version number and a date.
From: Vladislav Zolotarov @ 2010-12-08 11:43 UTC (permalink / raw)
  To: Dave Miller; +Cc: netdev list, Eilon Greenstein

Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/bnx2x/bnx2x.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index abbdf6d..7e4d682 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -20,8 +20,8 @@
  * (you will need to reboot afterwards) */
 /* #define BNX2X_STOP_ON_ERROR */
 
-#define DRV_MODULE_VERSION      "1.60.00-6"
-#define DRV_MODULE_RELDATE      "2010/11/29"
+#define DRV_MODULE_VERSION      "1.60.00-7"
+#define DRV_MODULE_RELDATE      "2010/12/08"
 #define BNX2X_BC_VER            0x040200
 
 #define BNX2X_MULTI_QUEUE
-- 
1.7.0.4





^ permalink raw reply related

* [patch 3/4] [PATCH] qeth: l3 add vlan hdr in passthru frames
From: frank.blaschka @ 2010-12-08 12:58 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390
In-Reply-To: <20101208125757.726629855@de.ibm.com>

[-- Attachment #1: 606-qeth-vlan-passthru.diff --]
[-- Type: text/plain, Size: 711 bytes --]

From: Frank Blaschka <frank.blaschka@de.ibm.com>

OSA l3 mode is hw accelerated VLAN only for IPv4. Take care we
add the vlan hdr to a passthru frame in the device driver.

Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---

 drivers/s390/net/qeth_l3_main.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -3115,7 +3115,7 @@ static int qeth_l3_hard_start_xmit(struc
 				skb_pull(new_skb, ETH_HLEN);
 		}
 
-		if (ipv == 6 && card->vlangrp &&
+		if (ipv != 4 && card->vlangrp &&
 				vlan_tx_tag_present(new_skb)) {
 			skb_push(new_skb, VLAN_HLEN);
 			skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4);


^ permalink raw reply

* [patch 2/4] [PATCH] qeth: support VIPA add/del in offline mode
From: frank.blaschka @ 2010-12-08 12:57 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, Einar Lueck
In-Reply-To: <20101208125757.726629855@de.ibm.com>

[-- Attachment #1: 605-qeth-vipa-offline.diff --]
[-- Type: text/plain, Size: 908 bytes --]

From: Einar Lueck <elelueck@de.ibm.com>

Only work through the IP adddress to do list if the card is UP or
SOFTSETUP. Enables to configure VIPA add/del in offline mode.

Signed-off-by: Einar Lueck <elelueck@de.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---

 drivers/s390/net/qeth_l3_main.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -456,8 +456,11 @@ static void qeth_l3_set_ip_addr_list(str
 	QETH_CARD_TEXT(card, 2, "sdiplist");
 	QETH_CARD_HEX(card, 2, &card, sizeof(void *));
 
-	if (card->options.sniffer)
+	if ((card->state != CARD_STATE_UP &&
+	     card->state != CARD_STATE_SOFTSETUP) || card->options.sniffer) {
 		return;
+	}
+
 	spin_lock_irqsave(&card->ip_lock, flags);
 	tbd_list = card->ip_tbd_list;
 	card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC);


^ permalink raw reply

* [patch 0/4] s390: qeth patches for net-next
From: frank.blaschka @ 2010-12-08 12:57 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390

Hi Dave,

here is another patch set for net-next.

shortlog:
Jan Glauber (1)
qeth: buffer count imbalance

Einar Lueck (2)
qeth: support ipv6 query arp cache for HiperSockets
qeth: support VIPA add/del in offline mode

Frank Blaschka (1)
qeth: l3 add vlan hdr in passthru frames

Thanks,
        Frank

^ permalink raw reply

* [patch 4/4] [PATCH] qeth: buffer count imbalance
From: frank.blaschka @ 2010-12-08 12:58 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, Jan Glauber
In-Reply-To: <20101208125757.726629855@de.ibm.com>

[-- Attachment #1: 137-qeth-buffer-imbalance.diff --]
[-- Type: text/plain, Size: 1110 bytes --]

From: Jan Glauber <jang@linux.vnet.ibm.com>

The used buffers counter is not incremented in case of an error so
the counter can become negative. Increment the used buffers counter
before checking for errors.

Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---

 drivers/s390/net/qeth_core_main.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2840,6 +2840,7 @@ static void qeth_flush_buffers(struct qe
 		queue->card->perf_stats.outbound_do_qdio_time +=
 			qeth_get_micros() -
 			queue->card->perf_stats.outbound_do_qdio_start_time;
+	atomic_add(count, &queue->used_buffers);
 	if (rc) {
 		queue->card->stats.tx_errors += count;
 		/* ignore temporary SIGA errors without busy condition */
@@ -2853,7 +2854,6 @@ static void qeth_flush_buffers(struct qe
 		qeth_schedule_recovery(queue->card);
 		return;
 	}
-	atomic_add(count, &queue->used_buffers);
 	if (queue->card->options.performance_stats)
 		queue->card->perf_stats.bufs_sent += count;
 }


^ permalink raw reply

* [patch 1/4] [PATCH] qeth: support ipv6 query arp cache for HiperSockets
From: frank.blaschka @ 2010-12-08 12:57 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, Einar Lueck
In-Reply-To: <20101208125757.726629855@de.ibm.com>

[-- Attachment #1: 601-qeth-ipv6-query-arp.diff --]
[-- Type: text/plain, Size: 12515 bytes --]

From: Einar Lueck <elelueck@de.ibm.com>

Function qeth_l3_arp_query now queries for IPv6 addresses, too, if
QETH_QARP_WITH_IPV6 is passed as parameter to the ioctl. HiperSockets
and GuestLAN in HiperSockets mode provide corresponding entries.

Signed-off-by: Einar Lueck <elelueck@de.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---

 arch/s390/include/asm/qeth.h     |   51 +++++++--
 drivers/s390/net/qeth_core_mpc.h |    2 
 drivers/s390/net/qeth_l3_main.c  |  219 +++++++++++++++++++++++++--------------
 3 files changed, 187 insertions(+), 85 deletions(-)

--- a/arch/s390/include/asm/qeth.h
+++ b/arch/s390/include/asm/qeth.h
@@ -28,39 +28,70 @@ struct qeth_arp_cache_entry {
 	__u8  reserved2[32];
 } __attribute__ ((packed));
 
+enum qeth_arp_ipaddrtype {
+	QETHARP_IP_ADDR_V4 = 1,
+	QETHARP_IP_ADDR_V6 = 2,
+};
+struct qeth_arp_entrytype {
+	__u8 mac;
+	__u8 ip;
+} __attribute__((packed));
+
+#define QETH_QARP_MEDIASPECIFIC_BYTES 32
+#define QETH_QARP_MACADDRTYPE_BYTES 1
 struct qeth_arp_qi_entry7 {
-	__u8 media_specific[32];
-	__u8 macaddr_type;
-	__u8 ipaddr_type;
+	__u8 media_specific[QETH_QARP_MEDIASPECIFIC_BYTES];
+	struct qeth_arp_entrytype type;
 	__u8 macaddr[6];
 	__u8 ipaddr[4];
 } __attribute__((packed));
 
+struct qeth_arp_qi_entry7_ipv6 {
+	__u8 media_specific[QETH_QARP_MEDIASPECIFIC_BYTES];
+	struct qeth_arp_entrytype type;
+	__u8 macaddr[6];
+	__u8 ipaddr[16];
+} __attribute__((packed));
+
 struct qeth_arp_qi_entry7_short {
-	__u8 macaddr_type;
-	__u8 ipaddr_type;
+	struct qeth_arp_entrytype type;
 	__u8 macaddr[6];
 	__u8 ipaddr[4];
 } __attribute__((packed));
 
+struct qeth_arp_qi_entry7_short_ipv6 {
+	struct qeth_arp_entrytype type;
+	__u8 macaddr[6];
+	__u8 ipaddr[16];
+} __attribute__((packed));
+
 struct qeth_arp_qi_entry5 {
-	__u8 media_specific[32];
-	__u8 macaddr_type;
-	__u8 ipaddr_type;
+	__u8 media_specific[QETH_QARP_MEDIASPECIFIC_BYTES];
+	struct qeth_arp_entrytype type;
 	__u8 ipaddr[4];
 } __attribute__((packed));
 
+struct qeth_arp_qi_entry5_ipv6 {
+	__u8 media_specific[QETH_QARP_MEDIASPECIFIC_BYTES];
+	struct qeth_arp_entrytype type;
+	__u8 ipaddr[16];
+} __attribute__((packed));
+
 struct qeth_arp_qi_entry5_short {
-	__u8 macaddr_type;
-	__u8 ipaddr_type;
+	struct qeth_arp_entrytype type;
 	__u8 ipaddr[4];
 } __attribute__((packed));
 
+struct qeth_arp_qi_entry5_short_ipv6 {
+	struct qeth_arp_entrytype type;
+	__u8 ipaddr[16];
+} __attribute__((packed));
 /*
  * can be set by user if no "media specific information" is wanted
  * -> saves a lot of space in user space buffer
  */
 #define QETH_QARP_STRIP_ENTRIES  0x8000
+#define QETH_QARP_WITH_IPV6	 0x4000
 #define QETH_QARP_REQUEST_MASK   0x00ff
 
 /* data sent to user space as result of query arp ioctl */
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -333,7 +333,7 @@ struct qeth_arp_query_data {
 	__u16 request_bits;
 	__u16 reply_bits;
 	__u32 no_entries;
-	char data;
+	char data; /* only for replies */
 } __attribute__((packed));
 
 /* used as parameter for arp_query reply */
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -30,6 +30,7 @@
 
 #include "qeth_l3.h"
 
+
 static int qeth_l3_set_offline(struct ccwgroup_device *);
 static int qeth_l3_recover(void *);
 static int qeth_l3_stop(struct net_device *);
@@ -2455,22 +2456,46 @@ static int qeth_l3_arp_set_no_entries(st
 	return rc;
 }
 
-static void qeth_l3_copy_arp_entries_stripped(struct qeth_arp_query_info *qinfo,
-		struct qeth_arp_query_data *qdata, int entry_size,
-		int uentry_size)
-{
-	char *entry_ptr;
-	char *uentry_ptr;
-	int i;
-
-	entry_ptr = (char *)&qdata->data;
-	uentry_ptr = (char *)(qinfo->udata + qinfo->udata_offset);
-	for (i = 0; i < qdata->no_entries; ++i) {
-		/* strip off 32 bytes "media specific information" */
-		memcpy(uentry_ptr, (entry_ptr + 32), entry_size - 32);
-		entry_ptr += entry_size;
-		uentry_ptr += uentry_size;
+static __u32 get_arp_entry_size(struct qeth_card *card,
+			struct qeth_arp_query_data *qdata,
+			struct qeth_arp_entrytype *type, __u8 strip_entries)
+{
+	__u32 rc;
+	__u8 is_hsi;
+
+	is_hsi = qdata->reply_bits == 5;
+	if (type->ip == QETHARP_IP_ADDR_V4) {
+		QETH_CARD_TEXT(card, 4, "arpev4");
+		if (strip_entries) {
+			rc = is_hsi ? sizeof(struct qeth_arp_qi_entry5_short) :
+				sizeof(struct qeth_arp_qi_entry7_short);
+		} else {
+			rc = is_hsi ? sizeof(struct qeth_arp_qi_entry5) :
+				sizeof(struct qeth_arp_qi_entry7);
+		}
+	} else if (type->ip == QETHARP_IP_ADDR_V6) {
+		QETH_CARD_TEXT(card, 4, "arpev6");
+		if (strip_entries) {
+			rc = is_hsi ?
+				sizeof(struct qeth_arp_qi_entry5_short_ipv6) :
+				sizeof(struct qeth_arp_qi_entry7_short_ipv6);
+		} else {
+			rc = is_hsi ?
+				sizeof(struct qeth_arp_qi_entry5_ipv6) :
+				sizeof(struct qeth_arp_qi_entry7_ipv6);
+		}
+	} else {
+		QETH_CARD_TEXT(card, 4, "arpinv");
+		rc = 0;
 	}
+
+	return rc;
+}
+
+static int arpentry_matches_prot(struct qeth_arp_entrytype *type, __u16 prot)
+{
+	return (type->ip == QETHARP_IP_ADDR_V4 && prot == QETH_PROT_IPV4) ||
+		(type->ip == QETHARP_IP_ADDR_V6 && prot == QETH_PROT_IPV6);
 }
 
 static int qeth_l3_arp_query_cb(struct qeth_card *card,
@@ -2479,72 +2504,77 @@ static int qeth_l3_arp_query_cb(struct q
 	struct qeth_ipa_cmd *cmd;
 	struct qeth_arp_query_data *qdata;
 	struct qeth_arp_query_info *qinfo;
-	int entry_size;
-	int uentry_size;
 	int i;
+	int e;
+	int entrybytes_done;
+	int stripped_bytes;
+	__u8 do_strip_entries;
 
-	QETH_CARD_TEXT(card, 4, "arpquecb");
+	QETH_CARD_TEXT(card, 3, "arpquecb");
 
 	qinfo = (struct qeth_arp_query_info *) reply->param;
 	cmd = (struct qeth_ipa_cmd *) data;
+	QETH_CARD_TEXT_(card, 4, "%i", cmd->hdr.prot_version);
 	if (cmd->hdr.return_code) {
-		QETH_CARD_TEXT_(card, 4, "qaer1%i", cmd->hdr.return_code);
+		QETH_CARD_TEXT(card, 4, "arpcberr");
+		QETH_CARD_TEXT_(card, 4, "%i", cmd->hdr.return_code);
 		return 0;
 	}
 	if (cmd->data.setassparms.hdr.return_code) {
 		cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code;
-		QETH_CARD_TEXT_(card, 4, "qaer2%i", cmd->hdr.return_code);
+		QETH_CARD_TEXT(card, 4, "setaperr");
+		QETH_CARD_TEXT_(card, 4, "%i", cmd->hdr.return_code);
 		return 0;
 	}
 	qdata = &cmd->data.setassparms.data.query_arp;
-	switch (qdata->reply_bits) {
-	case 5:
-		uentry_size = entry_size = sizeof(struct qeth_arp_qi_entry5);
-		if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES)
-			uentry_size = sizeof(struct qeth_arp_qi_entry5_short);
-		break;
-	case 7:
-		/* fall through to default */
-	default:
-		/* tr is the same as eth -> entry7 */
-		uentry_size = entry_size = sizeof(struct qeth_arp_qi_entry7);
-		if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES)
-			uentry_size = sizeof(struct qeth_arp_qi_entry7_short);
-		break;
-	}
-	/* check if there is enough room in userspace */
-	if ((qinfo->udata_len - qinfo->udata_offset) <
-			qdata->no_entries * uentry_size){
-		QETH_CARD_TEXT_(card, 4, "qaer3%i", -ENOMEM);
-		cmd->hdr.return_code = -ENOMEM;
-		goto out_error;
-	}
-	QETH_CARD_TEXT_(card, 4, "anore%i",
-		       cmd->data.setassparms.hdr.number_of_replies);
-	QETH_CARD_TEXT_(card, 4, "aseqn%i", cmd->data.setassparms.hdr.seq_no);
 	QETH_CARD_TEXT_(card, 4, "anoen%i", qdata->no_entries);
 
-	if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) {
-		/* strip off "media specific information" */
-		qeth_l3_copy_arp_entries_stripped(qinfo, qdata, entry_size,
-					       uentry_size);
-	} else
-		/*copy entries to user buffer*/
-		memcpy(qinfo->udata + qinfo->udata_offset,
-		       (char *)&qdata->data, qdata->no_entries*uentry_size);
+	do_strip_entries = (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) > 0;
+	stripped_bytes = do_strip_entries ? QETH_QARP_MEDIASPECIFIC_BYTES : 0;
+	entrybytes_done = 0;
+	for (e = 0; e < qdata->no_entries; ++e) {
+		char *cur_entry;
+		__u32 esize;
+		struct qeth_arp_entrytype *etype;
+
+		cur_entry = &qdata->data + entrybytes_done;
+		etype = &((struct qeth_arp_qi_entry5 *) cur_entry)->type;
+		if (!arpentry_matches_prot(etype, cmd->hdr.prot_version)) {
+			QETH_CARD_TEXT(card, 4, "pmis");
+			QETH_CARD_TEXT_(card, 4, "%i", etype->ip);
+			break;
+		}
+		esize = get_arp_entry_size(card, qdata, etype,
+			do_strip_entries);
+		QETH_CARD_TEXT_(card, 5, "esz%i", esize);
+		if (!esize)
+			break;
+
+		if ((qinfo->udata_len - qinfo->udata_offset) < esize) {
+			QETH_CARD_TEXT_(card, 4, "qaer3%i", -ENOMEM);
+			cmd->hdr.return_code = -ENOMEM;
+			goto out_error;
+		}
 
-	qinfo->no_entries += qdata->no_entries;
-	qinfo->udata_offset += (qdata->no_entries*uentry_size);
+		memcpy(qinfo->udata + qinfo->udata_offset,
+			&qdata->data + entrybytes_done + stripped_bytes,
+			esize);
+		entrybytes_done += esize + stripped_bytes;
+		qinfo->udata_offset += esize;
+		++qinfo->no_entries;
+	}
 	/* check if all replies received ... */
 	if (cmd->data.setassparms.hdr.seq_no <
 	    cmd->data.setassparms.hdr.number_of_replies)
 		return 1;
+	QETH_CARD_TEXT_(card, 4, "nove%i", qinfo->no_entries);
 	memcpy(qinfo->udata, &qinfo->no_entries, 4);
 	/* keep STRIP_ENTRIES flag so the user program can distinguish
 	 * stripped entries from normal ones */
 	if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES)
 		qdata->reply_bits |= QETH_QARP_STRIP_ENTRIES;
 	memcpy(qinfo->udata + QETH_QARP_MASK_OFFSET, &qdata->reply_bits, 2);
+	QETH_CARD_TEXT_(card, 4, "rc%i", 0);
 	return 0;
 out_error:
 	i = 0;
@@ -2567,45 +2597,86 @@ static int qeth_l3_send_ipa_arp_cmd(stru
 				      reply_cb, reply_param);
 }
 
-static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata)
+static int qeth_l3_query_arp_cache_info(struct qeth_card *card,
+	enum qeth_prot_versions prot,
+	struct qeth_arp_query_info *qinfo)
 {
 	struct qeth_cmd_buffer *iob;
-	struct qeth_arp_query_info qinfo = {0, };
+	struct qeth_ipa_cmd *cmd;
 	int tmp;
 	int rc;
 
+	QETH_CARD_TEXT_(card, 3, "qarpipv%i", prot);
+
+	iob = qeth_l3_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
+			IPA_CMD_ASS_ARP_QUERY_INFO,
+			sizeof(struct qeth_arp_query_data) - sizeof(char),
+			prot);
+	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
+	cmd->data.setassparms.data.query_arp.request_bits = 0x000F;
+	cmd->data.setassparms.data.query_arp.reply_bits = 0;
+	cmd->data.setassparms.data.query_arp.no_entries = 0;
+	rc = qeth_l3_send_ipa_arp_cmd(card, iob,
+			   QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN,
+			   qeth_l3_arp_query_cb, (void *)qinfo);
+	if (rc) {
+		tmp = rc;
+		QETH_DBF_MESSAGE(2,
+			"Error while querying ARP cache on %s: %s "
+			"(0x%x/%d)\n", QETH_CARD_IFNAME(card),
+			qeth_l3_arp_get_error_cause(&rc), tmp, tmp);
+	}
+
+	return rc;
+}
+
+static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata)
+{
+	struct qeth_arp_query_info qinfo = {0, };
+	int rc;
+
 	QETH_CARD_TEXT(card, 3, "arpquery");
 
 	if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/
 			       IPA_ARP_PROCESSING)) {
-		return -EOPNOTSUPP;
+		QETH_CARD_TEXT(card, 3, "arpqnsup");
+		rc = -EOPNOTSUPP;
+		goto out;
 	}
 	/* get size of userspace buffer and mask_bits -> 6 bytes */
-	if (copy_from_user(&qinfo, udata, 6))
-		return -EFAULT;
+	if (copy_from_user(&qinfo, udata, 6)) {
+		rc = -EFAULT;
+		goto out;
+	}
 	qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL);
-	if (!qinfo.udata)
-		return -ENOMEM;
+	if (!qinfo.udata) {
+		rc = -ENOMEM;
+		goto out;
+	}
 	qinfo.udata_offset = QETH_QARP_ENTRIES_OFFSET;
-	iob = qeth_l3_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
-				       IPA_CMD_ASS_ARP_QUERY_INFO,
-				       sizeof(int), QETH_PROT_IPV4);
-
-	rc = qeth_l3_send_ipa_arp_cmd(card, iob,
-				   QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN,
-				   qeth_l3_arp_query_cb, (void *)&qinfo);
+	rc = qeth_l3_query_arp_cache_info(card, QETH_PROT_IPV4, &qinfo);
 	if (rc) {
-		tmp = rc;
-		QETH_DBF_MESSAGE(2, "Error while querying ARP cache on %s: %s "
-			"(0x%x/%d)\n", QETH_CARD_IFNAME(card),
-			qeth_l3_arp_get_error_cause(&rc), tmp, tmp);
 		if (copy_to_user(udata, qinfo.udata, 4))
 			rc = -EFAULT;
+			goto free_and_out;
 	} else {
-		if (copy_to_user(udata, qinfo.udata, qinfo.udata_len))
+#ifdef CONFIG_QETH_IPV6
+		if (qinfo.mask_bits & QETH_QARP_WITH_IPV6) {
+			/* fails in case of GuestLAN QDIO mode */
+			qeth_l3_query_arp_cache_info(card, QETH_PROT_IPV6,
+				&qinfo);
+		}
+#endif
+		if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) {
+			QETH_CARD_TEXT(card, 4, "qactf");
 			rc = -EFAULT;
+			goto free_and_out;
+		}
+		QETH_CARD_TEXT_(card, 4, "qacts");
 	}
+free_and_out:
 	kfree(qinfo.udata);
+out:
 	return rc;
 }
 


^ permalink raw reply

* Re: bonding: flow control regression [was Re: bridging: flow control regression]
From: Simon Horman @ 2010-12-08 13:22 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, Jay Vosburgh, David S. Miller
In-Reply-To: <20101106092535.GD5128@verge.net.au>

On Sat, Nov 06, 2010 at 06:25:37PM +0900, Simon Horman wrote:
> On Tue, Nov 02, 2010 at 10:29:45AM +0100, Eric Dumazet wrote:
> > Le mardi 02 novembre 2010 à 17:46 +0900, Simon Horman a écrit :
> > 
> > > Thanks Eric, that seems to resolve the problem that I was seeing.
> > > 
> > > With your patch I see:
> > > 
> > > No bonding
> > > 
> > > # netperf -c -4 -t UDP_STREAM -H 172.17.60.216 -l 30 -- -m 1472
> > > UDP UNIDIRECTIONAL SEND TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 172.17.60.216 (172.17.60.216) port 0 AF_INET
> > > Socket  Message  Elapsed      Messages                   CPU      Service
> > > Size    Size     Time         Okay Errors   Throughput   Util     Demand
> > > bytes   bytes    secs            #      #   10^6bits/sec % SU     us/KB
> > > 
> > > 116736    1472   30.00     2438413      0      957.2     8.52     1.458 
> > > 129024           30.00     2438413             957.2     -1.00    -1.000
> > > 
> > > With bonding (one slave, the interface used in the test above)
> > > 
> > > netperf -c -4 -t UDP_STREAM -H 172.17.60.216 -l 30 -- -m 1472
> > > UDP UNIDIRECTIONAL SEND TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 172.17.60.216 (172.17.60.216) port 0 AF_INET
> > > Socket  Message  Elapsed      Messages                   CPU      Service
> > > Size    Size     Time         Okay Errors   Throughput   Util     Demand
> > > bytes   bytes    secs            #      #   10^6bits/sec % SU     us/KB
> > > 
> > > 116736    1472   30.00     2438390      0      957.1     8.97     1.535 
> > > 129024           30.00     2438390             957.1     -1.00    -1.000
> > > 
> > 
> > 
> > Sure the patch helps when not too many flows are involved, but this is a
> > hack.
> > 
> > Say the device queue is 1000 packets, and you run a workload with 2000
> > sockets, it wont work...
> > 
> > Or device queue is 1000 packets, one flow, and socket send queue size
> > allows for more than 1000 packets to be 'in flight' (echo 2000000
> > >/proc/sys/net/core/wmem_default) , it wont work too with bonding, only
> > with devices with a qdisc sitting in the first device met after the
> > socket.
> 
> True, thanks for pointing that out.
> 
> The scenario that I am actually interested in is virtualisation.
> And I believe that your patch helps the vhostnet case (I don't see
> flow control problems with bonding + virtio without vhostnet). However,
> I am unsure if there are also some easy work-arounds to degrade
> flow control in the vhostnet case too.

Hi Eric,

do you have any thoughts on this?

I measured the performance impact of your patch on 2.6.37-rc1
and I can see why early orphaning is a win.

The tests are run over a bond with 3 slaves.
The bond is in rr-balance mode. Other parameters of interest are:
	MTU=1500
	client,server:tcp_reordering=3(default)
	client:GSO=off,
	client:TSO=off
	server:GRO=off
	server:rx-usecs=3(default)

Without your no early-orphan patch
TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to
	172.17.60.216 (172.17.60.216) port 0 AF_INET
Recv   Send    Send                          Utilization       Service Demand
Socket Socket  Message  Elapsed              Send     Recv     Send    Recv
Size   Size    Size     Time     Throughput  local    remote   local   remote
bytes  bytes   bytes    secs.    10^6bits/s  % S      % U      us/KB   us/KB

 87380  16384  16384    10.00      1621.03   16.31    6.48     1.648   2.621

With your no early-orphan patch
# netperf -C -c -4 -t TCP_STREAM -H 172.17.60.216
TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to
	172.17.60.216 (172.17.60.216) port 0 AF_INET
Recv   Send    Send                          Utilization       Service Demand
Socket Socket  Message  Elapsed              Send     Recv     Send    Recv
Size   Size    Size     Time     Throughput  local    remote   local   remote
bytes  bytes   bytes    secs.    10^6bits/s  % S      % U      us/KB   us/KB

 87380  16384  16384    10.00      1433.48   9.60     5.45     1.098   2.490


However in the case of virtualisation I think it is a win to be able to do
flow control on UDP traffic from guests (using vitio). Am I missing
something and flow control can be bypassed anyway? If not perhaps making
the change that your patch makes configurable through proc or ethtool is an
option?


^ permalink raw reply

* Re: [PATCH 1/5] sysfs: Introducing binary attributes for struct class
From: Jiri Kosina @ 2010-12-08 13:33 UTC (permalink / raw)
  To: Stefan Achatz
  Cc: Randy Dunlap, Greg Kroah-Hartman, linux-doc, linux-kernel,
	linux-input, netdev
In-Reply-To: <1290801449.18750.162.camel@neuromancer>

On Fri, 26 Nov 2010, Stefan Achatz wrote:

> Added dev_bin_attrs to struct class similar to existing dev_attrs.
> 
> Signed-off-by: Stefan Achatz <erazor_de@users.sourceforge.net>

Greg, just to make sure (as you have stated your Ack in a thread belonging 
to different thread) -- I can add your Acked-by: to this patch and take it 
through my tree with the rest of the roccat patchset, is that correct?

Thanks.

-- 
Jiri Kosina
SUSE Labs, Novell Inc.

^ permalink raw reply

* Re: [regression, 2.6.37-rc1] 'ip link tap0 up' stuck in do_exit()
From: Oleg Nesterov @ 2010-12-08 13:41 UTC (permalink / raw)
  To: Florian Mickler
  Cc: Ingo Molnar, Américo Wang, Dave Chinner, Eric Dumazet,
	linux-kernel, netdev
In-Reply-To: <20101208100245.01cf23c5@schatten.dmk.lab>

On 12/08, Florian Mickler wrote:
>
> [ ccing Ingo and Oleg ] as suggested

Well. Of course I can't explain this bug. But, looking at this email
I do not see amything strange in exit/schedule/etc.

> > >> > > > This is resulting in the command 'ip link set tap0 up' hanging as a zombie:
> > >> > > >
> > >> > > > root      3005     1  0 16:53 pts/3    00:00:00 /bin/sh /vm-images/qemu-ifup tap0
> > >> > > > root      3011  3005  0 16:53 pts/3    00:00:00 /usr/bin/sudo /sbin/ip link set tap0 up
> > >> > > > root      3012  3011  0 16:53 pts/3    00:00:00 [ip] <defunct>

That is. ip is a zombie.

> > >> > > > In do_exit() with this trace:
> > >> > > >
> > >> > > > [ 1630.782255] ip            x ffff88063fcb3600     0  3012   3011 0x00000000
> > >> > > > [ 1630.789121]  ffff880631328000 0000000000000046 0000000000000000 ffff880633104380
> > >> > > > [ 1630.796524]  0000000000013600 ffff88062f031fd8 0000000000013600 0000000000013600
> > >> > > > [ 1630.803925]  ffff8806313282d8 ffff8806313282e0 ffff880631328000 0000000000013600
> > >> > > > [ 1630.811324] Call Trace:
> > >> > > > [ 1630.813760]  [<ffffffff8104a90d>] ? do_exit+0x716/0x724
> > >> > > > [ 1630.818964]  [<ffffffff8104a995>] ? do_group_exit+0x7a/0xa4
> > >> > > > [ 1630.824512]  [<ffffffff8104a9d1>] ? sys_exit_group+0x12/0x16
> > >> > > > [ 1630.830149]  [<ffffffff81009a82>] ? system_call_fastpath+0x16/0x1b
> > >> > > >
> > >> > > > The address comes down to the schedule() call:
> > >> > > >
> > >> > > > (gdb) l *(do_exit+0x716)
> > >> > > > 0xffffffff8104a90d is in do_exit (kernel/exit.c:1034).
> > >> > > > 1029            preempt_disable();
> > >> > > > 1030            exit_rcu();
> > >> > > > 1031            /* causes final put_task_struct in finish_task_switch(). */
> > >> > > > 1032            tsk->state = TASK_DEAD;
> > >> > > > 1033            schedule();
> > >> > > > 1034            BUG();
> > >> > > > 1035            /* Avoid "noreturn function does return".  */
> > >> > > > 1036            for (;;)
> > >> > > > 1037                    cpu_relax();    /* For when BUG is null */
> > >> > > > 1038    }

Everything is correct. The task is dead, but it wasn't released by its
parent, task_struct (and thus the stack) is still visible.

> > Interesting, the scheduler failed to put the dead task out of
> > run queue, so to me this is likely to be a scheduler bug.
> > I have no idea how sudo can change the behaviour here.
> >
> > Another guess is we need a smp_wmb() before schedule() above.

No, everything looks fine.

For example,

	$ perl -le 'print fork || exit; <>'
	17436

	$ ps 17436
	  PID TTY      STAT   TIME COMMAND
	17436 pts/22   Z+     0:00 [perl] <defunct>

	$ cat /proc/17436/stack
	[<ffffffff8104d3a0>] do_exit+0x6c4/0x6d2
	[<ffffffff8104d429>] do_group_exit+0x7b/0xa4
	[<ffffffff8104d469>] sys_exit_group+0x17/0x1b
	[<ffffffff8100bdb2>] system_call_fastpath+0x16/0x1b
	[<ffffffffffffffff>] 0xffffffffffffffff

Oleg.

^ permalink raw reply

* [PATCH] ss: Change "do now" to "do not" in ss(8), -n option
From: Petr Sabata @ 2010-12-08 13:49 UTC (permalink / raw)
  To: netdev; +Cc: Petr Sabata

A small typo fix.

---
 man/man8/ss.8 |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/man/man8/ss.8 b/man/man8/ss.8
index f261cf2..b309df2 100644
--- a/man/man8/ss.8
+++ b/man/man8/ss.8
@@ -26,7 +26,7 @@ Show summary of options.
 Output version information.
 .TP
 .B \-n, \-\-numeric
-Do now try to resolve service names.
+Do not try to resolve service names.
 .TP
 .B \-r, \-\-resolve
 Try to resolve numeric address/ports.
-- 
1.7.3.2


^ permalink raw reply related

* Re: bonding: flow control regression [was Re: bridging: flow control regression]
From: Eric Dumazet @ 2010-12-08 13:50 UTC (permalink / raw)
  To: Simon Horman; +Cc: netdev, Jay Vosburgh, David S. Miller
In-Reply-To: <20101208132217.GA28040@verge.net.au>

Le mercredi 08 décembre 2010 à 22:22 +0900, Simon Horman a écrit :

> Hi Eric,
> 
> do you have any thoughts on this?
> 
> I measured the performance impact of your patch on 2.6.37-rc1
> and I can see why early orphaning is a win.
> 
> The tests are run over a bond with 3 slaves.
> The bond is in rr-balance mode. Other parameters of interest are:
> 	MTU=1500
> 	client,server:tcp_reordering=3(default)
> 	client:GSO=off,
> 	client:TSO=off
> 	server:GRO=off
> 	server:rx-usecs=3(default)
> 
> Without your no early-orphan patch
> TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to
> 	172.17.60.216 (172.17.60.216) port 0 AF_INET
> Recv   Send    Send                          Utilization       Service Demand
> Socket Socket  Message  Elapsed              Send     Recv     Send    Recv
> Size   Size    Size     Time     Throughput  local    remote   local   remote
> bytes  bytes   bytes    secs.    10^6bits/s  % S      % U      us/KB   us/KB
> 
>  87380  16384  16384    10.00      1621.03   16.31    6.48     1.648   2.621
> 
> With your no early-orphan patch
> # netperf -C -c -4 -t TCP_STREAM -H 172.17.60.216
> TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to
> 	172.17.60.216 (172.17.60.216) port 0 AF_INET
> Recv   Send    Send                          Utilization       Service Demand
> Socket Socket  Message  Elapsed              Send     Recv     Send    Recv
> Size   Size    Size     Time     Throughput  local    remote   local   remote
> bytes  bytes   bytes    secs.    10^6bits/s  % S      % U      us/KB   us/KB
> 
>  87380  16384  16384    10.00      1433.48   9.60     5.45     1.098   2.490
> 

It seems strange this makes such big difference with one flow


> 
> However in the case of virtualisation I think it is a win to be able to do
> flow control on UDP traffic from guests (using vitio). Am I missing
> something and flow control can be bypassed anyway? If not perhaps making
> the change that your patch makes configurable through proc or ethtool is an
> option?
> 

virtio_net start_xmit() does one skb_orphan() anyway, so not doing it
some nano seconds before wont change anything.

Real perf problem is when skb are queued (for example on eth driver TX
ring or qdisc queue), then freed some micro (or milli) seconds later.

Maybe your ethtool suggestion is the way to go, so that we can remove
special "skb_orphans()" that can be done in some drivers : Let core
network stack decide to skb_orphan() itself, not the driver.




^ permalink raw reply

* Re: [regression, 2.6.37-rc1] 'ip link tap0 up' stuck in do_exit()
From: Oleg Nesterov @ 2010-12-08 13:47 UTC (permalink / raw)
  To: Florian Mickler
  Cc: Ingo Molnar, Américo Wang, Dave Chinner, Eric Dumazet,
	linux-kernel, netdev
In-Reply-To: <20101208134116.GA16923@redhat.com>

On 12/08, Oleg Nesterov wrote:
>
> On 12/08, Florian Mickler wrote:
> >
> > [ ccing Ingo and Oleg ] as suggested
>
> Well. Of course I can't explain this bug. But, looking at this email
> I do not see amything strange in exit/schedule/etc.
>
> > > >> > > > This is resulting in the command 'ip link set tap0 up' hanging as a zombie:
> > > >> > > >
> > > >> > > > root      3005     1  0 16:53 pts/3    00:00:00 /bin/sh /vm-images/qemu-ifup tap0
> > > >> > > > root      3011  3005  0 16:53 pts/3    00:00:00 /usr/bin/sudo /sbin/ip link set tap0 up
> > > >> > > > root      3012  3011  0 16:53 pts/3    00:00:00 [ip] <defunct>
>
> That is. ip is a zombie.

And. I do not know if this matters or not, but "the command 'ip link
set tap0 up' hanging as a zombie" does not look right.

This was spawned by

> >> > > > if [ -n "$1" ];then
> >> > > >         /usr/bin/sudo /sbin/ip link set $1 up
> >> > > >         sleep 0.5s
> >> > > >         /usr/bin/sudo /usr/sbin/brctl addif $switch $1
> >> > > >      exit 0
> >> > > > fi

The command does not hang. But it forks the child with pid == 3012,
this child exits.

Oleg.


^ permalink raw reply

* Re: [v3 PATCH 1/2] bonding: sync netpoll code with bridge
From: Neil Horman @ 2010-12-08 13:57 UTC (permalink / raw)
  To: Amerigo Wang
  Cc: linux-kernel, Jiri Pirko, netdev, David S. Miller,
	Eric W. Biederman, Herbert Xu, bonding-devel, Jay Vosburgh,
	Stephen Hemminger
In-Reply-To: <20101208075208.5792.45247.sendpatchset@localhost.localdomain>

On Wed, Dec 08, 2010 at 02:52:08AM -0500, Amerigo Wang wrote:
> From: Amerigo Wang <amwang@redhat.com>
> Date: Thu, 2 Dec 2010 21:31:19 +0800
> Subject: [v3 PATCH 1/2] bonding: sync netpoll code with bridge
> 
> V3: remove an useless #ifdef.
> 
> This patch unifies the netpoll code in bonding with netpoll code in bridge,
> thanks to Herbert that code is much cleaner now.
> 
> Signed-off-by: WANG Cong <amwang@redhat.com>
> Cc: Neil Horman <nhorman@redhat.com>
> Cc: Herbert Xu <herbert@gondor.apana.org.au>
> Cc: Jay Vosburgh <fubar@us.ibm.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Stephen Hemminger <shemminger@vyatta.com>
> Cc: Jiri Pirko <jpirko@redhat.com>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> 
> 
> ---
> 
>  drivers/net/bonding/bond_main.c |  155 ++++++++++++++++++++++++--------------
>  drivers/net/bonding/bonding.h   |   20 +++++
>  2 files changed, 118 insertions(+), 57 deletions(-)
> 
> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> index 0273ad0..7fafe06 100644
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -59,7 +59,6 @@
>  #include <linux/uaccess.h>
>  #include <linux/errno.h>
>  #include <linux/netdevice.h>
> -#include <linux/netpoll.h>
>  #include <linux/inetdevice.h>
>  #include <linux/igmp.h>
>  #include <linux/etherdevice.h>
> @@ -449,15 +448,11 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
>  	}
>  
>  	skb->priority = 1;
> -#ifdef CONFIG_NET_POLL_CONTROLLER
> -	if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) {
> -		struct netpoll *np = bond->dev->npinfo->netpoll;
> -		slave_dev->npinfo = bond->dev->npinfo;
> +	if (unlikely(netpoll_tx_running(slave_dev))) {
>  		slave_dev->priv_flags |= IFF_IN_NETPOLL;
> -		netpoll_send_skb_on_dev(np, skb, slave_dev);
> +		bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb);
>  		slave_dev->priv_flags &= ~IFF_IN_NETPOLL;
>  	} else
> -#endif
>  		dev_queue_xmit(skb);
>  
>  	return 0;
> @@ -1310,63 +1305,113 @@ static void bond_detach_slave(struct bonding *bond, struct slave *slave)
>  }
>  
>  #ifdef CONFIG_NET_POLL_CONTROLLER
> -/*
> - * You must hold read lock on bond->lock before calling this.
> - */
> -static bool slaves_support_netpoll(struct net_device *bond_dev)
> +static inline int slave_enable_netpoll(struct slave *slave)
>  {
> -	struct bonding *bond = netdev_priv(bond_dev);
> -	struct slave *slave;
> -	int i = 0;
> -	bool ret = true;
> +	struct netpoll *np;
> +	int err = 0;
>  
> -	bond_for_each_slave(bond, slave, i) {
> -		if ((slave->dev->priv_flags & IFF_DISABLE_NETPOLL) ||
> -		    !slave->dev->netdev_ops->ndo_poll_controller)
> -			ret = false;
> +	np = kmalloc(sizeof(*np), GFP_KERNEL);
> +	err = -ENOMEM;
> +	if (!np)
> +		goto out;
> +
> +	np->dev = slave->dev;
> +	err = __netpoll_setup(np);
Setting up our own netpoll instance on each slave worries me a bit.  The
implication here is that, by doing so, some frames will get entirely processed
by the slave.  Most notably arp frames.  That means anything that gets queued up
to the arp_tx queue in __netpoll_rx will get processed during that poll event,
and responded to with the mac of the slave device, rather than with the mac of
the bond device, which isn't always what you want.  I think if you go with this
route, you'll need to add code to netpoll_poll_dev, right before the call to
service_arp_queue, to check if IFF_SLAVE is set in priv_flags, and move the list
to the master device, or some such.

It also seems like you'll want to zero out the other fields in the netpoll
structure.  Leaving garbage in them will be bad.  Most notably here I'm looking
at the rx_hook field.  If its non-null we're going to add a bogus pointer to the
rx_np list and call off into space at some point.

> +	if (err) {
> +		kfree(np);
> +		goto out;
>  	}
> -	return i != 0 && ret;
> +	slave->np = np;
> +out:
> +	return err;
> +}
> +static inline void slave_disable_netpoll(struct slave *slave)
> +{
> +	struct netpoll *np = slave->np;
> +
> +	if (!np)
> +		return;
> +
> +	slave->np = NULL;
> +	synchronize_rcu_bh();
> +	__netpoll_cleanup(np);
> +	kfree(np);
> +}
> +static inline bool slave_dev_support_netpoll(struct net_device *slave_dev)
> +{
> +	if (slave_dev->priv_flags & IFF_DISABLE_NETPOLL)
> +		return false;
> +	if (!slave_dev->netdev_ops->ndo_poll_controller)
> +		return false;
> +	return true;
>  }
>  
>  static void bond_poll_controller(struct net_device *bond_dev)
>  {
> -	struct bonding *bond = netdev_priv(bond_dev);
> +}
> +
> +static void __bond_netpoll_cleanup(struct bonding *bond)
> +{
>  	struct slave *slave;
>  	int i;
>  
> -	bond_for_each_slave(bond, slave, i) {
> -		if (slave->dev && IS_UP(slave->dev))
> -			netpoll_poll_dev(slave->dev);
> -	}
> +	bond_for_each_slave(bond, slave, i)
> +		if (slave->dev)
Why are you checking slave->dev here?  If the dev pointer has been set to NULL
here it would seem we're not holding on to dev long enough.  If we enabled
netpoll with a dev pointer and lost it somewhere along the way, we're going to
leak that struct netpoll memory that we allocated.

> +			slave_disable_netpoll(slave);
>  }
> -
>  static void bond_netpoll_cleanup(struct net_device *bond_dev)
>  {
>  	struct bonding *bond = netdev_priv(bond_dev);
> +
> +	read_lock(&bond->lock);
> +	__bond_netpoll_cleanup(bond);
> +	read_unlock(&bond->lock);
> +}
> +
> +static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni)
> +{
> +	struct bonding *bond = netdev_priv(dev);
>  	struct slave *slave;
> -	const struct net_device_ops *ops;
> -	int i;
> +	int i, err = 0;
>  
>  	read_lock(&bond->lock);
> -	bond_dev->npinfo = NULL;
>  	bond_for_each_slave(bond, slave, i) {
> -		if (slave->dev) {
> -			ops = slave->dev->netdev_ops;
> -			if (ops->ndo_netpoll_cleanup)
> -				ops->ndo_netpoll_cleanup(slave->dev);
> -			else
> -				slave->dev->npinfo = NULL;
> +		if (!slave->dev)
> +			continue;
> +		err = slave_enable_netpoll(slave);
> +		if (err) {
> +			__bond_netpoll_cleanup(bond);
> +			break;
>  		}
>  	}
>  	read_unlock(&bond->lock);
> +	return err;
>  }
>  
> -#else
> +static struct netpoll_info *bond_netpoll_info(struct bonding *bond)
> +{
> +	return bond->dev->npinfo;
> +}
>  
> +#else
> +static inline int slave_enable_netpoll(struct slave *slave)
> +{
> +	return 0;
> +}
> +static inline void slave_disable_netpoll(struct slave *slave)
> +{
> +}
>  static void bond_netpoll_cleanup(struct net_device *bond_dev)
>  {
>  }
> -
> +static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni)
> +{
> +	return 0;
> +}
> +static struct netpoll_info *bond_netpoll_info(struct bonding *bond)
> +{
> +	return NULL;
> +}
>  #endif
>  
>  /*---------------------------------- IOCTL ----------------------------------*/
> @@ -1804,17 +1849,19 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
>  	bond_set_carrier(bond);
>  
>  #ifdef CONFIG_NET_POLL_CONTROLLER
> -	if (slaves_support_netpoll(bond_dev)) {
> -		bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
> -		if (bond_dev->npinfo)
> -			slave_dev->npinfo = bond_dev->npinfo;
> -	} else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) {
> -		bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
> -		pr_info("New slave device %s does not support netpoll\n",
> -			slave_dev->name);
> -		pr_info("Disabling netpoll support for %s\n", bond_dev->name);
> +	slave_dev->npinfo = bond_netpoll_info(bond);
> +	if (slave_dev->npinfo) {
> +		if (slave_enable_netpoll(new_slave)) {
> +			read_unlock(&bond->lock);
> +			pr_info("Error, %s: master_dev is using netpoll, "
> +				 "but new slave device does not support netpoll.\n",
> +				 bond_dev->name);
> +			res = -EBUSY;
> +			goto err_close;
> +		}
>  	}
>  #endif
> +
>  	read_unlock(&bond->lock);
>  
>  	res = bond_create_slave_symlinks(bond_dev, slave_dev);
> @@ -2016,17 +2063,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
>  
>  	netdev_set_master(slave_dev, NULL);
>  
> -#ifdef CONFIG_NET_POLL_CONTROLLER
> -	read_lock_bh(&bond->lock);
> -
> -	if (slaves_support_netpoll(bond_dev))
> -		bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
> -	read_unlock_bh(&bond->lock);
> -	if (slave_dev->netdev_ops->ndo_netpoll_cleanup)
> -		slave_dev->netdev_ops->ndo_netpoll_cleanup(slave_dev);
> -	else
> -		slave_dev->npinfo = NULL;
> -#endif
> +	slave_disable_netpoll(slave);
>  
>  	/* close slave before restoring its mac address */
>  	dev_close(slave_dev);
> @@ -2061,6 +2098,7 @@ static int  bond_release_and_destroy(struct net_device *bond_dev,
>  
>  	ret = bond_release(bond_dev, slave_dev);
>  	if ((ret == 0) && (bond->slave_cnt == 0)) {
> +		bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
Why are you setting IFF_DISABLE_NETPOLL here?  That seems unnecessecary

>  		pr_info("%s: destroying bond %s.\n",
>  			bond_dev->name, bond_dev->name);
>  		unregister_netdevice(bond_dev);
> @@ -2138,6 +2176,8 @@ static int bond_release_all(struct net_device *bond_dev)
>  
>  		netdev_set_master(slave_dev, NULL);
>  
> +		slave_disable_netpoll(slave);
> +
>  		/* close slave before restoring its mac address */
>  		dev_close(slave_dev);
>  
> @@ -4670,6 +4710,7 @@ static const struct net_device_ops bond_netdev_ops = {
>  	.ndo_vlan_rx_add_vid 	= bond_vlan_rx_add_vid,
>  	.ndo_vlan_rx_kill_vid	= bond_vlan_rx_kill_vid,
>  #ifdef CONFIG_NET_POLL_CONTROLLER
> +	.ndo_netpoll_setup	= bond_netpoll_setup,
>  	.ndo_netpoll_cleanup	= bond_netpoll_cleanup,
>  	.ndo_poll_controller	= bond_poll_controller,
>  #endif
> diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
> index ad3ae46..c4f6a94 100644
> --- a/drivers/net/bonding/bonding.h
> +++ b/drivers/net/bonding/bonding.h
> @@ -21,6 +21,7 @@
>  #include <linux/kobject.h>
>  #include <linux/cpumask.h>
>  #include <linux/in6.h>
> +#include <linux/netpoll.h>
>  #include "bond_3ad.h"
>  #include "bond_alb.h"
>  
> @@ -203,6 +204,9 @@ struct slave {
>  	u16    queue_id;
>  	struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */
>  	struct tlb_slave_info tlb_info;
> +#ifdef CONFIG_NET_POLL_CONTROLLER
> +	struct netpoll *np;
> +#endif
>  };
>  
>  /*
> @@ -324,6 +328,22 @@ static inline unsigned long slave_last_rx(struct bonding *bond,
>  	return slave->dev->last_rx;
>  }
>  
> +#ifdef CONFIG_NET_POLL_CONTROLLER
> +static inline void bond_netpoll_send_skb(const struct slave *slave,
> +					 struct sk_buff *skb)
> +{
> +	struct netpoll *np = slave->np;
> +
> +	if (np)
> +		netpoll_send_skb(np, skb);
> +}
> +#else
> +static inline void bond_netpoll_send_skb(const struct slave *slave,
> +					 struct sk_buff *skb)
> +{
> +}
> +#endif
> +
>  static inline void bond_set_slave_inactive_flags(struct slave *slave)
>  {
>  	struct bonding *bond = netdev_priv(slave->dev->master);
> -- 
> 1.7.1
> 

^ permalink raw reply

* Re: [regression, 2.6.37-rc1] 'ip link tap0 up' stuck in do_exit()
From: Oleg Nesterov @ 2010-12-08 14:08 UTC (permalink / raw)
  To: Florian Mickler
  Cc: Ingo Molnar, Américo Wang, Dave Chinner, Eric Dumazet,
	linux-kernel, netdev
In-Reply-To: <20101208134712.GB16923@redhat.com>

On 12/08, Oleg Nesterov wrote:
>
> On 12/08, Oleg Nesterov wrote:
> >
> > On 12/08, Florian Mickler wrote:
> > >
> > > [ ccing Ingo and Oleg ] as suggested
> >
> > Well. Of course I can't explain this bug. But, looking at this email
> > I do not see amything strange in exit/schedule/etc.
> >
> > > > >> > > > This is resulting in the command 'ip link set tap0 up' hanging as a zombie:
> > > > >> > > >
> > > > >> > > > root      3005     1  0 16:53 pts/3    00:00:00 /bin/sh /vm-images/qemu-ifup tap0
> > > > >> > > > root      3011  3005  0 16:53 pts/3    00:00:00 /usr/bin/sudo /sbin/ip link set tap0 up
> > > > >> > > > root      3012  3011  0 16:53 pts/3    00:00:00 [ip] <defunct>
> >
> > That is. ip is a zombie.
>
> And. I do not know if this matters or not, but "the command 'ip link
> set tap0 up' hanging as a zombie" does not look right.
>
> This was spawned by
>
> > >> > > > if [ -n "$1" ];then
> > >> > > >         /usr/bin/sudo /sbin/ip link set $1 up
> > >> > > >         sleep 0.5s
> > >> > > >         /usr/bin/sudo /usr/sbin/brctl addif $switch $1
> > >> > > >      exit 0
> > >> > > > fi
>
> The command does not hang. But it forks the child with pid == 3012,
> this child exits.

Damn, sorry for noise, forgot to mention...

The parent's trace (pid == 3011) can be more useful. Say, if it
hangs in do_wait(), then the kernel is obviously wrong.

Oleg.

^ permalink raw reply

* [PATCH 0/3] xfrm: ESP Traffic Flow Confidentiality padding (v3)
From: Martin Willi @ 2010-12-08 14:37 UTC (permalink / raw)
  To: Herbert Xu; +Cc: linux-crypto, netdev

The following patchset adds Traffic Flow Confidentiality padding. The
first patch introduces a new Netlink XFRM attribute to configure TFC via
userspace. Patch two and three implement the padding logic in IPv4 and
IPv6 ESP. Padding is always done using the RFC4303 format an is clamped
to the PMTU.

Changes from v2:
  - Remove unused flag field in attribute, use a plain u32 as attribute payload
  - Reject installation of TFC padding on non-tunnel SAs

Martin Willi (3):
      xfrm: Add Traffic Flow Confidentiality padding XFRM attribute
      xfrm: Traffic Flow Confidentiality for IPv4 ESP
      xfrm: Traffic Flow Confidentiality for IPv6 ESP

 include/linux/xfrm.h |    1 +
 include/net/xfrm.h   |    1 +
 net/ipv4/esp4.c      |   32 ++++++++++++++++++++++++--------
 net/ipv6/esp6.c      |   32 ++++++++++++++++++++++++--------
 net/xfrm/xfrm_user.c |   19 +++++++++++++++++--
 5 files changed, 67 insertions(+), 18 deletions(-)

^ permalink raw reply

* [PATCH 2/3] xfrm: Traffic Flow Confidentiality for IPv4 ESP
From: Martin Willi @ 2010-12-08 14:37 UTC (permalink / raw)
  To: Herbert Xu; +Cc: linux-crypto, netdev
In-Reply-To: <1291819071-17538-1-git-send-email-martin@strongswan.org>

Add TFC padding to all packets smaller than the boundary configured
on the xfrm state. If the boundary is larger than the PMTU, limit
padding to the PMTU.

Signed-off-by: Martin Willi <martin@strongswan.org>
---
 net/ipv4/esp4.c |   32 ++++++++++++++++++++++++--------
 1 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 14ca1f1..e42a905 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -23,6 +23,8 @@ struct esp_skb_cb {
 
 #define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
 
+static u32 esp4_get_mtu(struct xfrm_state *x, int mtu);
+
 /*
  * Allocate an AEAD request structure with extra space for SG and IV.
  *
@@ -117,25 +119,35 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
 	int blksize;
 	int clen;
 	int alen;
+	int plen;
+	int tfclen;
 	int nfrags;
 
 	/* skb is pure payload to encrypt */
 
 	err = -ENOMEM;
 
-	/* Round to block size */
-	clen = skb->len;
-
 	esp = x->data;
 	aead = esp->aead;
 	alen = crypto_aead_authsize(aead);
 
+	tfclen = 0;
+	if (x->tfcpad) {
+		struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
+		u32 padto;
+
+		padto = min(x->tfcpad, esp4_get_mtu(x, dst->child_mtu_cached));
+		if (skb->len < padto)
+			tfclen = padto - skb->len;
+	}
 	blksize = ALIGN(crypto_aead_blocksize(aead), 4);
-	clen = ALIGN(clen + 2, blksize);
+	clen = ALIGN(skb->len + 2 + tfclen, blksize);
 	if (esp->padlen)
 		clen = ALIGN(clen, esp->padlen);
+	plen = clen - skb->len - tfclen;
 
-	if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0)
+	err = skb_cow_data(skb, tfclen + plen + alen, &trailer);
+	if (err < 0)
 		goto error;
 	nfrags = err;
 
@@ -150,13 +162,17 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
 
 	/* Fill padding... */
 	tail = skb_tail_pointer(trailer);
+	if (tfclen) {
+		memset(tail, 0, tfclen);
+		tail += tfclen;
+	}
 	do {
 		int i;
-		for (i=0; i<clen-skb->len - 2; i++)
+		for (i = 0; i < plen - 2; i++)
 			tail[i] = i + 1;
 	} while (0);
-	tail[clen - skb->len - 2] = (clen - skb->len) - 2;
-	tail[clen - skb->len - 1] = *skb_mac_header(skb);
+	tail[plen - 2] = plen - 2;
+	tail[plen - 1] = *skb_mac_header(skb);
 	pskb_put(skb, trailer, clen - skb->len + alen);
 
 	skb_push(skb, -skb_network_offset(skb));
-- 
1.7.1

^ permalink raw reply related

* [PATCH 3/3] xfrm: Traffic Flow Confidentiality for IPv6 ESP
From: Martin Willi @ 2010-12-08 14:37 UTC (permalink / raw)
  To: Herbert Xu; +Cc: linux-crypto, netdev
In-Reply-To: <1291819071-17538-1-git-send-email-martin@strongswan.org>

Add TFC padding to all packets smaller than the boundary configured
on the xfrm state. If the boundary is larger than the PMTU, limit
padding to the PMTU.

Signed-off-by: Martin Willi <martin@strongswan.org>
---
 net/ipv6/esp6.c |   32 ++++++++++++++++++++++++--------
 1 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index ee9b93b..1b5c982 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -49,6 +49,8 @@ struct esp_skb_cb {
 
 #define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
 
+static u32 esp6_get_mtu(struct xfrm_state *x, int mtu);
+
 /*
  * Allocate an AEAD request structure with extra space for SG and IV.
  *
@@ -140,6 +142,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
 	int blksize;
 	int clen;
 	int alen;
+	int plen;
+	int tfclen;
 	int nfrags;
 	u8 *iv;
 	u8 *tail;
@@ -148,18 +152,26 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
 	/* skb is pure payload to encrypt */
 	err = -ENOMEM;
 
-	/* Round to block size */
-	clen = skb->len;
-
 	aead = esp->aead;
 	alen = crypto_aead_authsize(aead);
 
+	tfclen = 0;
+	if (x->tfcpad) {
+		struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
+		u32 padto;
+
+		padto = min(x->tfcpad, esp6_get_mtu(x, dst->child_mtu_cached));
+		if (skb->len < padto)
+			tfclen = padto - skb->len;
+	}
 	blksize = ALIGN(crypto_aead_blocksize(aead), 4);
-	clen = ALIGN(clen + 2, blksize);
+	clen = ALIGN(skb->len + 2 + tfclen, blksize);
 	if (esp->padlen)
 		clen = ALIGN(clen, esp->padlen);
+	plen = clen - skb->len - tfclen;
 
-	if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0)
+	err = skb_cow_data(skb, tfclen + plen + alen, &trailer);
+	if (err < 0)
 		goto error;
 	nfrags = err;
 
@@ -174,13 +186,17 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
 
 	/* Fill padding... */
 	tail = skb_tail_pointer(trailer);
+	if (tfclen) {
+		memset(tail, 0, tfclen);
+		tail += tfclen;
+	}
 	do {
 		int i;
-		for (i=0; i<clen-skb->len - 2; i++)
+		for (i = 0; i < plen - 2; i++)
 			tail[i] = i + 1;
 	} while (0);
-	tail[clen-skb->len - 2] = (clen - skb->len) - 2;
-	tail[clen - skb->len - 1] = *skb_mac_header(skb);
+	tail[plen - 2] = plen - 2;
+	tail[plen - 1] = *skb_mac_header(skb);
 	pskb_put(skb, trailer, clen - skb->len + alen);
 
 	skb_push(skb, -skb_network_offset(skb));
-- 
1.7.1

^ permalink raw reply related

* [PATCH 1/3] xfrm: Add Traffic Flow Confidentiality padding XFRM attribute
From: Martin Willi @ 2010-12-08 14:37 UTC (permalink / raw)
  To: Herbert Xu; +Cc: linux-crypto, netdev
In-Reply-To: <1291819071-17538-1-git-send-email-martin@strongswan.org>

The XFRMA_TFCPAD attribute for XFRM state installation configures
Traffic Flow Confidentiality by padding ESP packets to a specified
length.

Signed-off-by: Martin Willi <martin@strongswan.org>
---
 include/linux/xfrm.h |    1 +
 include/net/xfrm.h   |    1 +
 net/xfrm/xfrm_user.c |   19 +++++++++++++++++--
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index b971e38..930fdd2 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -283,6 +283,7 @@ enum xfrm_attr_type_t {
 	XFRMA_KMADDRESS,        /* struct xfrm_user_kmaddress */
 	XFRMA_ALG_AUTH_TRUNC,	/* struct xfrm_algo_auth */
 	XFRMA_MARK,		/* struct xfrm_mark */
+	XFRMA_TFCPAD,		/* __u32 */
 	__XFRMA_MAX
 
 #define XFRMA_MAX (__XFRMA_MAX - 1)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index bcfb6b2..bdcade7 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -143,6 +143,7 @@ struct xfrm_state {
 	struct xfrm_id		id;
 	struct xfrm_selector	sel;
 	struct xfrm_mark	mark;
+	u32			tfcpad;
 
 	u32			genid;
 
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 8bae6b2..8eb8895 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -148,7 +148,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
 		     !attrs[XFRMA_ALG_AUTH_TRUNC]) ||
 		    attrs[XFRMA_ALG_AEAD]	||
 		    attrs[XFRMA_ALG_CRYPT]	||
-		    attrs[XFRMA_ALG_COMP])
+		    attrs[XFRMA_ALG_COMP]	||
+		    attrs[XFRMA_TFCPAD])
 			goto out;
 		break;
 
@@ -165,6 +166,9 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
 		     attrs[XFRMA_ALG_CRYPT]) &&
 		    attrs[XFRMA_ALG_AEAD])
 			goto out;
+		if (attrs[XFRMA_TFCPAD] &&
+		    p->mode != XFRM_MODE_TUNNEL)
+			goto out;
 		break;
 
 	case IPPROTO_COMP:
@@ -172,7 +176,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
 		    attrs[XFRMA_ALG_AEAD]	||
 		    attrs[XFRMA_ALG_AUTH]	||
 		    attrs[XFRMA_ALG_AUTH_TRUNC]	||
-		    attrs[XFRMA_ALG_CRYPT])
+		    attrs[XFRMA_ALG_CRYPT]	||
+		    attrs[XFRMA_TFCPAD])
 			goto out;
 		break;
 
@@ -186,6 +191,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
 		    attrs[XFRMA_ALG_CRYPT]	||
 		    attrs[XFRMA_ENCAP]		||
 		    attrs[XFRMA_SEC_CTX]	||
+		    attrs[XFRMA_TFCPAD]		||
 		    !attrs[XFRMA_COADDR])
 			goto out;
 		break;
@@ -439,6 +445,9 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
 			goto error;
 	}
 
+	if (attrs[XFRMA_TFCPAD])
+		x->tfcpad = nla_get_u32(attrs[XFRMA_TFCPAD]);
+
 	if (attrs[XFRMA_COADDR]) {
 		x->coaddr = kmemdup(nla_data(attrs[XFRMA_COADDR]),
 				    sizeof(*x->coaddr), GFP_KERNEL);
@@ -688,6 +697,9 @@ static int copy_to_user_state_extra(struct xfrm_state *x,
 	if (x->encap)
 		NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
 
+	if (x->tfcpad)
+		NLA_PUT_U32(skb, XFRMA_TFCPAD, x->tfcpad);
+
 	if (xfrm_mark_put(skb, &x->mark))
 		goto nla_put_failure;
 
@@ -2122,6 +2134,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
 	[XFRMA_MIGRATE]		= { .len = sizeof(struct xfrm_user_migrate) },
 	[XFRMA_KMADDRESS]	= { .len = sizeof(struct xfrm_user_kmaddress) },
 	[XFRMA_MARK]		= { .len = sizeof(struct xfrm_mark) },
+	[XFRMA_TFCPAD]		= { .type = NLA_U32 },
 };
 
 static struct xfrm_link {
@@ -2301,6 +2314,8 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x)
 		l += nla_total_size(sizeof(*x->calg));
 	if (x->encap)
 		l += nla_total_size(sizeof(*x->encap));
+	if (x->tfcpad)
+		l += nla_total_size(sizeof(x->tfcpad));
 	if (x->security)
 		l += nla_total_size(sizeof(struct xfrm_user_sec_ctx) +
 				    x->security->ctx_len);
-- 
1.7.1


^ permalink raw reply related

* Polling on sockets in kernel space and struct file
From: Martin Sustrik @ 2010-12-08 14:33 UTC (permalink / raw)
  To: netdev; +Cc: Martin Lucina

Hi all,

As part of implementing a new experimental protocol family, we are 
trying to create a socket in kernel. This seems to be easy, just use 
sock_create_kern(). However, the socket returned by this function does 
not have associated file structure; thus it cannot be polled on using 
poll_initwait() and friends.

We have tried to create the appropriate struct file using sock_map_fd(), 
but this has two problems:

1) We do not want our internal socket to be visible in the process 
context, i.e. it should not have a file descriptor.

2) During process exit, we get a kernel BUG from iput() in fs/inode.c:1260.

We then tried another approach using anon_inode_getfile() to get a 
struct file, but this still produces the problem 2) above.

Any help/advice on how to proceed would be appreciated; for reference 
our work in progress can be seen at

http://github.com/sustrik/linux-2.6/blob/sp-v2.6.36/net/sp/af_sp.c

Thanks,

Martin

^ permalink raw reply

* Re: Polling on sockets in kernel space and struct file
From: Eric Dumazet @ 2010-12-08 15:02 UTC (permalink / raw)
  To: Martin Sustrik; +Cc: netdev, Martin Lucina
In-Reply-To: <4CFF9757.3070100@250bpm.com>

Le mercredi 08 décembre 2010 à 15:33 +0100, Martin Sustrik a écrit :
> Hi all,
> 
> As part of implementing a new experimental protocol family, we are 
> trying to create a socket in kernel. This seems to be easy, just use 
> sock_create_kern(). However, the socket returned by this function does 
> not have associated file structure; thus it cannot be polled on using 
> poll_initwait() and friends.
> 
> We have tried to create the appropriate struct file using sock_map_fd(), 
> but this has two problems:
> 
> 1) We do not want our internal socket to be visible in the process 
> context, i.e. it should not have a file descriptor.



> 
> 2) During process exit, we get a kernel BUG from iput() in fs/inode.c:1260.
> 

you could call sock_map_fd() then :


	int fd = sock_map_fd(sock, flags);
	struct file *file = NULL;

	if (fd != -1) {
		file = fget(fd);
		sys_close(fd);  /* still racy */
	}

	if (file) ...

Take a look at net/9p/trans_fd.c

> We then tried another approach using anon_inode_getfile() to get a 
> struct file, but this still produces the problem 2) above.
> 
> Any help/advice on how to proceed would be appreciated; for reference 
> our work in progress can be seen at
> 
> http://github.com/sustrik/linux-2.6/blob/sp-v2.6.36/net/sp/af_sp.c



^ permalink raw reply

* rndis gadget: Inconsistent locking
From: Neil Jones @ 2010-12-08 15:03 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA

Hi,

Im getting another lockdep warning when using the RNDIS gadget:

 WARNING: at kernel/softirq.c:98 ___local_bh_disable+0xc4/0xd0()
 Modules linked in: g_ether

 Call trace:
 [<40003bf8>] _show_stack+0x68/0x7c
 [<40003c20>] _dump_stack+0x14/0x28
 [<40013c3c>] _warn_slowpath_common+0x5c/0x7c
 [<40013c74>] _warn_slowpath_null+0x18/0x2c
 [<4001b17c>] ___local_bh_disable+0xc0/0xd0
 [<4001b1a0>] _local_bh_disable+0x14/0x28
 [<402e57f8>] __raw_spin_lock_bh+0x18/0x54
 [<40257f4c>] _dev_txq_stats_fold+0x7c/0x13c
 [<402580c4>] _dev_get_stats+0xb8/0xc0
 [<781d4e60>] _rndis_msg_parser+0x288/0xa04 [g_ether]
 [<781d5600>] _rndis_command_complete+0x24/0x70 [g_ether]
 [<401d66fc>] _dwc_otg_request_done+0xd8/0x220
 [<401d928c>] _ep0_complete_request+0x3f4/0x578
 [<401d95bc>] _handle_ep0+0x1ac/0x146c
 [<401daf7c>] _dwc_otg_pcd_handle_in_ep_intr+0x1c0/0x8bc
 [<401db8dc>] _dwc_otg_pcd_handle_intr+0x264/0x294
 [<401d6288>] _dwc_otg_pcd_irq+0x10/0x30
 [<40054cf4>] _handle_IRQ_event+0x4c/0x184
 [<40057b4c>] _handle_level_irq+0xac/0x15c
 [<4000b204>] _metag_soc_irq_demux+0xac/0xb4
 [<40002dd4>] _do_IRQ+0x4c/0x78
 [<40004000>] _trigger_handler+0x38/0xac
 [<40000b18>] ___TBIBoingVec+0xc/0x10
 [<40003588>] _cpu_idle+0x54/0x78

 no locks held by swapper/0.
 ---[ end trace 77ac3cfee0ae5b25 ]---

It
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 1/5] sysfs: Introducing binary attributes for struct class
From: Greg KH @ 2010-12-08 15:06 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Stefan Achatz, Randy Dunlap, linux-doc, linux-kernel, linux-input,
	netdev
In-Reply-To: <alpine.LNX.2.00.1012081432230.14806@pobox.suse.cz>

On Wed, Dec 08, 2010 at 02:33:14PM +0100, Jiri Kosina wrote:
> On Fri, 26 Nov 2010, Stefan Achatz wrote:
> 
> > Added dev_bin_attrs to struct class similar to existing dev_attrs.
> > 
> > Signed-off-by: Stefan Achatz <erazor_de@users.sourceforge.net>
> 
> Greg, just to make sure (as you have stated your Ack in a thread belonging 
> to different thread) -- I can add your Acked-by: to this patch and take it 
> through my tree with the rest of the roccat patchset, is that correct?

Yes you can.

thanks,

greg k-h

^ permalink raw reply

* Re: rndis gadget: Inconsistent locking
From: Neil Jones @ 2010-12-08 15:11 UTC (permalink / raw)
  To: linux-usb, netdev
In-Reply-To: <AANLkTik=Uui7Xk9ZfFvQQKj94ZJUJ_n+bZbTQXbe+08i@mail.gmail.com>

Sorry, stupid gmail...

Hi,

Im getting another lockdep warning when using the RNDIS gadget:

 WARNING: at kernel/softirq.c:98 ___local_bh_disable+0xc4/0xd0()
 Modules linked in: g_ether

 Call trace:
 [<40003bf8>] _show_stack+0x68/0x7c
 [<40003c20>] _dump_stack+0x14/0x28
 [<40013c3c>] _warn_slowpath_common+0x5c/0x7c
 [<40013c74>] _warn_slowpath_null+0x18/0x2c
 [<4001b17c>] ___local_bh_disable+0xc0/0xd0
 [<4001b1a0>] _local_bh_disable+0x14/0x28
 [<402e57f8>] __raw_spin_lock_bh+0x18/0x54
 [<40257f4c>] _dev_txq_stats_fold+0x7c/0x13c
 [<402580c4>] _dev_get_stats+0xb8/0xc0
 [<781d4e60>] _rndis_msg_parser+0x288/0xa04 [g_ether]
 [<781d5600>] _rndis_command_complete+0x24/0x70 [g_ether]
 [<401d66fc>] _dwc_otg_request_done+0xd8/0x220
 [<401d928c>] _ep0_complete_request+0x3f4/0x578
 [<401d95bc>] _handle_ep0+0x1ac/0x146c
 [<401daf7c>] _dwc_otg_pcd_handle_in_ep_intr+0x1c0/0x8bc
 [<401db8dc>] _dwc_otg_pcd_handle_intr+0x264/0x294
 [<401d6288>] _dwc_otg_pcd_irq+0x10/0x30
 [<40054cf4>] _handle_IRQ_event+0x4c/0x184
 [<40057b4c>] _handle_level_irq+0xac/0x15c
 [<4000b204>] _metag_soc_irq_demux+0xac/0xb4
 [<40002dd4>] _do_IRQ+0x4c/0x78
 [<40004000>] _trigger_handler+0x38/0xac
 [<40000b18>] ___TBIBoingVec+0xc/0x10
 [<40003588>] _cpu_idle+0x54/0x78

 no locks held by swapper/0.
 ---[ end trace 77ac3cfee0ae5b25 ]---

It looks like we are calling spin_lock_bh in the completion function
which is running in hard_irq, I think the driver should defer handling
this msg (and maybe all requests) to a workqueue?

Cheers

Neil



On Wed, Dec 8, 2010 at 3:03 PM, Neil Jones <neiljay@gmail.com> wrote:
> Hi,
>
> Im getting another lockdep warning when using the RNDIS gadget:
>
>  WARNING: at kernel/softirq.c:98 ___local_bh_disable+0xc4/0xd0()
>  Modules linked in: g_ether
>
>  Call trace:
>  [<40003bf8>] _show_stack+0x68/0x7c
>  [<40003c20>] _dump_stack+0x14/0x28
>  [<40013c3c>] _warn_slowpath_common+0x5c/0x7c
>  [<40013c74>] _warn_slowpath_null+0x18/0x2c
>  [<4001b17c>] ___local_bh_disable+0xc0/0xd0
>  [<4001b1a0>] _local_bh_disable+0x14/0x28
>  [<402e57f8>] __raw_spin_lock_bh+0x18/0x54
>  [<40257f4c>] _dev_txq_stats_fold+0x7c/0x13c
>  [<402580c4>] _dev_get_stats+0xb8/0xc0
>  [<781d4e60>] _rndis_msg_parser+0x288/0xa04 [g_ether]
>  [<781d5600>] _rndis_command_complete+0x24/0x70 [g_ether]
>  [<401d66fc>] _dwc_otg_request_done+0xd8/0x220
>  [<401d928c>] _ep0_complete_request+0x3f4/0x578
>  [<401d95bc>] _handle_ep0+0x1ac/0x146c
>  [<401daf7c>] _dwc_otg_pcd_handle_in_ep_intr+0x1c0/0x8bc
>  [<401db8dc>] _dwc_otg_pcd_handle_intr+0x264/0x294
>  [<401d6288>] _dwc_otg_pcd_irq+0x10/0x30
>  [<40054cf4>] _handle_IRQ_event+0x4c/0x184
>  [<40057b4c>] _handle_level_irq+0xac/0x15c
>  [<4000b204>] _metag_soc_irq_demux+0xac/0xb4
>  [<40002dd4>] _do_IRQ+0x4c/0x78
>  [<40004000>] _trigger_handler+0x38/0xac
>  [<40000b18>] ___TBIBoingVec+0xc/0x10
>  [<40003588>] _cpu_idle+0x54/0x78
>
>  no locks held by swapper/0.
>  ---[ end trace 77ac3cfee0ae5b25 ]---
>
> It
>

^ 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