All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net 0/3] s390/qeth patches for net
@ 2017-03-23 13:55 Ursula Braun
  2017-03-23 13:55 ` [PATCH net 1/3] s390/qeth: size calculation outbound buffers Ursula Braun
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Ursula Braun @ 2017-03-23 13:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl, ubraun

Hi Dave,

here are 2 s390/qeth patches built for net fixing a problem with AF_IUCV
traffic through HiperSockets.
And we come up with an update for the MAINTAINERS file to establish
Julian as Co-Maintainer for drivers/s390/net and net/iucv.

Thanks, Ursula

Julian Wiedmann (2):
  s390/qeth: size calculation outbound buffers
  s390/qeth: no ETH header for outbound AF_IUCV

Ursula Braun (1):
  MAINTAINERS: add Julian Wiedmann

 MAINTAINERS                       |  2 ++
 drivers/s390/net/qeth_core.h      |  3 ++-
 drivers/s390/net/qeth_core_main.c |  5 +++--
 drivers/s390/net/qeth_l2_main.c   |  5 +++--
 drivers/s390/net/qeth_l3_main.c   | 20 +++++++-------------
 5 files changed, 17 insertions(+), 18 deletions(-)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH net 1/3] s390/qeth: size calculation outbound buffers
  2017-03-23 13:55 [PATCH net 0/3] s390/qeth patches for net Ursula Braun
@ 2017-03-23 13:55 ` Ursula Braun
  2017-03-23 13:55 ` [PATCH net 2/3] s390/qeth: no ETH header for outbound AF_IUCV Ursula Braun
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Ursula Braun @ 2017-03-23 13:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl, ubraun

From: Julian Wiedmann <jwi@linux.vnet.ibm.com>

Depending on the device type, hard_start_xmit() builds different output
buffer formats. For instance with HiperSockets, on both L2 and L3 we
strip the ETH header from the skb - L3 doesn't need it, and L2 carries
it in the buffer's header element.
For this, we pass data_offset = ETH_HLEN all the way down to
__qeth_fill_buffer(), where skb->data is then adjusted accordingly.
But the initial size calculation still considers the *full* skb length
(including the ETH header). So qeth_get_elements_no() can erroneously
reject a skb as too big, even though it would actually fit into an
output buffer once the ETH header has been trimmed off later.

Fix this by passing an additional offset to qeth_get_elements_no(),
that indicates where in the skb the on-wire data actually begins.
Since the current code uses data_offset=-1 for some special handling
on OSA, we need to clamp data_offset to 0...

On HiperSockets this helps when sending ~MTU-size skbs with weird page
alignment. No change for OSA or AF_IUCV.

Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
---
 drivers/s390/net/qeth_core.h      | 3 ++-
 drivers/s390/net/qeth_core_main.c | 5 +++--
 drivers/s390/net/qeth_l2_main.c   | 5 +++--
 drivers/s390/net/qeth_l3_main.c   | 5 +++--
 4 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index e7addea..d9561e3 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -961,7 +961,8 @@ int qeth_bridgeport_query_ports(struct qeth_card *card,
 int qeth_bridgeport_setrole(struct qeth_card *card, enum qeth_sbp_roles role);
 int qeth_bridgeport_an_set(struct qeth_card *card, int enable);
 int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int);
-int qeth_get_elements_no(struct qeth_card *, struct sk_buff *, int);
+int qeth_get_elements_no(struct qeth_card *card, struct sk_buff *skb,
+			 int extra_elems, int data_offset);
 int qeth_get_elements_for_frags(struct sk_buff *);
 int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *,
 			struct sk_buff *, struct qeth_hdr *, int, int, int);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 315d8a2..9a5f99c 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -3837,6 +3837,7 @@ EXPORT_SYMBOL_GPL(qeth_get_elements_for_frags);
  * @card:			qeth card structure, to check max. elems.
  * @skb:			SKB address
  * @extra_elems:		extra elems needed, to check against max.
+ * @data_offset:		range starts at skb->data + data_offset
  *
  * Returns the number of pages, and thus QDIO buffer elements, needed to cover
  * skb data, including linear part and fragments. Checks if the result plus
@@ -3844,10 +3845,10 @@ EXPORT_SYMBOL_GPL(qeth_get_elements_for_frags);
  * Note: extra_elems is not included in the returned result.
  */
 int qeth_get_elements_no(struct qeth_card *card,
-		     struct sk_buff *skb, int extra_elems)
+		     struct sk_buff *skb, int extra_elems, int data_offset)
 {
 	int elements = qeth_get_elements_for_range(
-				(addr_t)skb->data,
+				(addr_t)skb->data + data_offset,
 				(addr_t)skb->data + skb_headlen(skb)) +
 			qeth_get_elements_for_frags(skb);
 
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index bea4833..af4e6a6 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -849,7 +849,7 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	 * chaining we can not send long frag lists
 	 */
 	if ((card->info.type != QETH_CARD_TYPE_IQD) &&
-	    !qeth_get_elements_no(card, new_skb, 0)) {
+	    !qeth_get_elements_no(card, new_skb, 0, 0)) {
 		int lin_rc = skb_linearize(new_skb);
 
 		if (card->options.performance_stats) {
@@ -894,7 +894,8 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		}
 	}
 
-	elements = qeth_get_elements_no(card, new_skb, elements_needed);
+	elements = qeth_get_elements_no(card, new_skb, elements_needed,
+					(data_offset > 0) ? data_offset : 0);
 	if (!elements) {
 		if (data_offset >= 0)
 			kmem_cache_free(qeth_core_header_cache, hdr);
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 06d0add..72aa953 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2867,7 +2867,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	 */
 	if ((card->info.type != QETH_CARD_TYPE_IQD) &&
 	    ((use_tso && !qeth_l3_get_elements_no_tso(card, new_skb, 1)) ||
-	     (!use_tso && !qeth_get_elements_no(card, new_skb, 0)))) {
+	     (!use_tso && !qeth_get_elements_no(card, new_skb, 0, 0)))) {
 		int lin_rc = skb_linearize(new_skb);
 
 		if (card->options.performance_stats) {
@@ -2909,7 +2909,8 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	elements = use_tso ?
 		   qeth_l3_get_elements_no_tso(card, new_skb, hdr_elements) :
-		   qeth_get_elements_no(card, new_skb, hdr_elements);
+		   qeth_get_elements_no(card, new_skb, hdr_elements,
+					(data_offset > 0) ? data_offset : 0);
 	if (!elements) {
 		if (data_offset >= 0)
 			kmem_cache_free(qeth_core_header_cache, hdr);
-- 
2.8.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH net 2/3] s390/qeth: no ETH header for outbound AF_IUCV
  2017-03-23 13:55 [PATCH net 0/3] s390/qeth patches for net Ursula Braun
  2017-03-23 13:55 ` [PATCH net 1/3] s390/qeth: size calculation outbound buffers Ursula Braun
@ 2017-03-23 13:55 ` Ursula Braun
  2017-03-23 13:55 ` [PATCH net 3/3] MAINTAINERS: add Julian Wiedmann Ursula Braun
  2017-03-24 19:40 ` [PATCH net 0/3] s390/qeth patches for net David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Ursula Braun @ 2017-03-23 13:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl, ubraun

From: Julian Wiedmann <jwi@linux.vnet.ibm.com>

With AF_IUCV traffic, the skb passed to hard_start_xmit() has a 14 byte
slot at skb->data, intended for an ETH header. qeth_l3_fill_af_iucv_hdr()
fills this ETH header... and then immediately moves it to the
skb's headroom, where it disappears and is never seen again.

But it's still possible for us to return NETDEV_TX_BUSY after the skb has
been modified. Since we didn't get a private copy of the skb, the next
time the skb is delivered to hard_start_xmit() it no longer has the
expected layout (we moved the ETH header to the headroom, so skb->data
now starts at the IUCV_TRANS header). So when qeth_l3_fill_af_iucv_hdr()
does another round of rebuilding, the resulting qeth header ends up
all wrong. On transmission, the buffer is then rejected by
the HiperSockets device with SBALF15 = x'04'.
When this error is passed back to af_iucv as TX_NOTIFY_UNREACHABLE, it
tears down the offending socket.

As the ETH header for AF_IUCV serves no purpose, just align the code to
what we do for IP traffic on L3 HiperSockets: keep the ETH header at
skb->data, and pass down data_offset = ETH_HLEN to qeth_fill_buffer().
When mapping the payload into the SBAL elements, the ETH header is then
stripped off. This avoids the skb manipulations in
qeth_l3_fill_af_iucv_hdr(), and any buffer re-entering hard_start_xmit()
after NETDEV_TX_BUSY is now processed properly.

Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
---
 drivers/s390/net/qeth_l3_main.c | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 72aa953..653f0fb 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2609,17 +2609,13 @@ static void qeth_l3_fill_af_iucv_hdr(struct qeth_card *card,
 	char daddr[16];
 	struct af_iucv_trans_hdr *iucv_hdr;
 
-	skb_pull(skb, 14);
-	card->dev->header_ops->create(skb, card->dev, 0,
-				      card->dev->dev_addr, card->dev->dev_addr,
-				      card->dev->addr_len);
-	skb_pull(skb, 14);
-	iucv_hdr = (struct af_iucv_trans_hdr *)skb->data;
 	memset(hdr, 0, sizeof(struct qeth_hdr));
 	hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3;
 	hdr->hdr.l3.ext_flags = 0;
-	hdr->hdr.l3.length = skb->len;
+	hdr->hdr.l3.length = skb->len - ETH_HLEN;
 	hdr->hdr.l3.flags = QETH_HDR_IPV6 | QETH_CAST_UNICAST;
+
+	iucv_hdr = (struct af_iucv_trans_hdr *) (skb->data + ETH_HLEN);
 	memset(daddr, 0, sizeof(daddr));
 	daddr[0] = 0xfe;
 	daddr[1] = 0x80;
@@ -2823,10 +2819,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if ((card->info.type == QETH_CARD_TYPE_IQD) &&
 	    !skb_is_nonlinear(skb)) {
 		new_skb = skb;
-		if (new_skb->protocol == ETH_P_AF_IUCV)
-			data_offset = 0;
-		else
-			data_offset = ETH_HLEN;
+		data_offset = ETH_HLEN;
 		hdr = kmem_cache_alloc(qeth_core_header_cache, GFP_ATOMIC);
 		if (!hdr)
 			goto tx_drop;
-- 
2.8.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH net 3/3] MAINTAINERS: add Julian Wiedmann
  2017-03-23 13:55 [PATCH net 0/3] s390/qeth patches for net Ursula Braun
  2017-03-23 13:55 ` [PATCH net 1/3] s390/qeth: size calculation outbound buffers Ursula Braun
  2017-03-23 13:55 ` [PATCH net 2/3] s390/qeth: no ETH header for outbound AF_IUCV Ursula Braun
@ 2017-03-23 13:55 ` Ursula Braun
  2017-03-24 19:40 ` [PATCH net 0/3] s390/qeth patches for net David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Ursula Braun @ 2017-03-23 13:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl, ubraun

Add Julian Wiedmann as additional maintainer for drivers/s390/net
and net/iucv.

Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index c45c02b..e48678d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10808,6 +10808,7 @@ F:	drivers/s390/block/dasd*
 F:	block/partitions/ibm.c
 
 S390 NETWORK DRIVERS
+M:	Julian Wiedmann <jwi@linux.vnet.ibm.com>
 M:	Ursula Braun <ubraun@linux.vnet.ibm.com>
 L:	linux-s390@vger.kernel.org
 W:	http://www.ibm.com/developerworks/linux/linux390/
@@ -10838,6 +10839,7 @@ S:	Supported
 F:	drivers/s390/scsi/zfcp_*
 
 S390 IUCV NETWORK LAYER
+M:	Julian Wiedmann <jwi@linux.vnet.ibm.com>
 M:	Ursula Braun <ubraun@linux.vnet.ibm.com>
 L:	linux-s390@vger.kernel.org
 W:	http://www.ibm.com/developerworks/linux/linux390/
-- 
2.8.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net 0/3] s390/qeth patches for net
  2017-03-23 13:55 [PATCH net 0/3] s390/qeth patches for net Ursula Braun
                   ` (2 preceding siblings ...)
  2017-03-23 13:55 ` [PATCH net 3/3] MAINTAINERS: add Julian Wiedmann Ursula Braun
@ 2017-03-24 19:40 ` David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2017-03-24 19:40 UTC (permalink / raw)
  To: ubraun; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl

From: Ursula Braun <ubraun@linux.vnet.ibm.com>
Date: Thu, 23 Mar 2017 14:55:07 +0100

> here are 2 s390/qeth patches built for net fixing a problem with AF_IUCV
> traffic through HiperSockets.
> And we come up with an update for the MAINTAINERS file to establish
> Julian as Co-Maintainer for drivers/s390/net and net/iucv.

Series applied, thank you.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-03-24 19:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-23 13:55 [PATCH net 0/3] s390/qeth patches for net Ursula Braun
2017-03-23 13:55 ` [PATCH net 1/3] s390/qeth: size calculation outbound buffers Ursula Braun
2017-03-23 13:55 ` [PATCH net 2/3] s390/qeth: no ETH header for outbound AF_IUCV Ursula Braun
2017-03-23 13:55 ` [PATCH net 3/3] MAINTAINERS: add Julian Wiedmann Ursula Braun
2017-03-24 19:40 ` [PATCH net 0/3] s390/qeth patches for net David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.