Skip to content

Commit 99838e6

Browse files
committed
Merge branch 'af_iucv-fixes'
Julian Wiedmann says: ==================== net/af_iucv: fixes 2019-06-18 I spent a few cycles on transmit problems for af_iucv over regular netdevices - please apply the following fixes to -net. The first patch allows for skb allocations outside of GFP_DMA, while the second patch respects that drivers might use skb_cow_head() and/or want additional dev->needed_headroom. Patch 3 is for a separate issue, where we didn't setup some of the netdevice-specific infrastructure when running as a z/VM guest. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 48620e3 + 06996c1 commit 99838e6

File tree

1 file changed

+36
-13
lines changed

1 file changed

+36
-13
lines changed

net/iucv/af_iucv.c

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
1515

1616
#include <linux/module.h>
17+
#include <linux/netdevice.h>
1718
#include <linux/types.h>
1819
#include <linux/list.h>
1920
#include <linux/errno.h>
@@ -347,14 +348,14 @@ static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock,
347348
if (imsg)
348349
memcpy(&phs_hdr->iucv_hdr, imsg, sizeof(struct iucv_message));
349350

350-
skb_push(skb, ETH_HLEN);
351-
memset(skb->data, 0, ETH_HLEN);
352-
353351
skb->dev = iucv->hs_dev;
354352
if (!skb->dev) {
355353
err = -ENODEV;
356354
goto err_free;
357355
}
356+
357+
dev_hard_header(skb, skb->dev, ETH_P_AF_IUCV, NULL, NULL, skb->len);
358+
358359
if (!(skb->dev->flags & IFF_UP) || !netif_carrier_ok(skb->dev)) {
359360
err = -ENETDOWN;
360361
goto err_free;
@@ -367,6 +368,8 @@ static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock,
367368
skb_trim(skb, skb->dev->mtu);
368369
}
369370
skb->protocol = cpu_to_be16(ETH_P_AF_IUCV);
371+
372+
__skb_header_release(skb);
370373
nskb = skb_clone(skb, GFP_ATOMIC);
371374
if (!nskb) {
372375
err = -ENOMEM;
@@ -466,12 +469,14 @@ static void iucv_sever_path(struct sock *sk, int with_user_data)
466469
/* Send controlling flags through an IUCV socket for HIPER transport */
467470
static int iucv_send_ctrl(struct sock *sk, u8 flags)
468471
{
472+
struct iucv_sock *iucv = iucv_sk(sk);
469473
int err = 0;
470474
int blen;
471475
struct sk_buff *skb;
472476
u8 shutdown = 0;
473477

474-
blen = sizeof(struct af_iucv_trans_hdr) + ETH_HLEN;
478+
blen = sizeof(struct af_iucv_trans_hdr) +
479+
LL_RESERVED_SPACE(iucv->hs_dev);
475480
if (sk->sk_shutdown & SEND_SHUTDOWN) {
476481
/* controlling flags should be sent anyway */
477482
shutdown = sk->sk_shutdown;
@@ -588,7 +593,6 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio,
588593

589594
sk->sk_destruct = iucv_sock_destruct;
590595
sk->sk_sndtimeo = IUCV_CONN_TIMEOUT;
591-
sk->sk_allocation = GFP_DMA;
592596

593597
sock_reset_flag(sk, SOCK_ZAPPED);
594598

@@ -782,6 +786,7 @@ static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr,
782786
memcpy(iucv->src_user_id, iucv_userid, 8);
783787
sk->sk_state = IUCV_BOUND;
784788
iucv->transport = AF_IUCV_TRANS_IUCV;
789+
sk->sk_allocation |= GFP_DMA;
785790
if (!iucv->msglimit)
786791
iucv->msglimit = IUCV_QUEUELEN_DEFAULT;
787792
goto done_unlock;
@@ -806,6 +811,8 @@ static int iucv_sock_autobind(struct sock *sk)
806811
return -EPROTO;
807812

808813
memcpy(iucv->src_user_id, iucv_userid, 8);
814+
iucv->transport = AF_IUCV_TRANS_IUCV;
815+
sk->sk_allocation |= GFP_DMA;
809816

810817
write_lock_bh(&iucv_sk_list.lock);
811818
__iucv_auto_name(iucv);
@@ -1131,7 +1138,8 @@ static int iucv_sock_sendmsg(struct socket *sock, struct msghdr *msg,
11311138
* segmented records using the MSG_EOR flag), but
11321139
* for SOCK_STREAM we might want to improve it in future */
11331140
if (iucv->transport == AF_IUCV_TRANS_HIPER) {
1134-
headroom = sizeof(struct af_iucv_trans_hdr) + ETH_HLEN;
1141+
headroom = sizeof(struct af_iucv_trans_hdr) +
1142+
LL_RESERVED_SPACE(iucv->hs_dev);
11351143
linear = len;
11361144
} else {
11371145
if (len < PAGE_SIZE) {
@@ -1781,6 +1789,8 @@ static int iucv_callback_connreq(struct iucv_path *path,
17811789

17821790
niucv = iucv_sk(nsk);
17831791
iucv_sock_init(nsk, sk);
1792+
niucv->transport = AF_IUCV_TRANS_IUCV;
1793+
nsk->sk_allocation |= GFP_DMA;
17841794

17851795
/* Set the new iucv_sock */
17861796
memcpy(niucv->dst_name, ipuser + 8, 8);
@@ -2430,6 +2440,13 @@ static int afiucv_iucv_init(void)
24302440
return err;
24312441
}
24322442

2443+
static void afiucv_iucv_exit(void)
2444+
{
2445+
device_unregister(af_iucv_dev);
2446+
driver_unregister(&af_iucv_driver);
2447+
pr_iucv->iucv_unregister(&af_iucv_handler, 0);
2448+
}
2449+
24332450
static int __init afiucv_init(void)
24342451
{
24352452
int err;
@@ -2463,11 +2480,18 @@ static int __init afiucv_init(void)
24632480
err = afiucv_iucv_init();
24642481
if (err)
24652482
goto out_sock;
2466-
} else
2467-
register_netdevice_notifier(&afiucv_netdev_notifier);
2483+
}
2484+
2485+
err = register_netdevice_notifier(&afiucv_netdev_notifier);
2486+
if (err)
2487+
goto out_notifier;
2488+
24682489
dev_add_pack(&iucv_packet_type);
24692490
return 0;
24702491

2492+
out_notifier:
2493+
if (pr_iucv)
2494+
afiucv_iucv_exit();
24712495
out_sock:
24722496
sock_unregister(PF_IUCV);
24732497
out_proto:
@@ -2481,12 +2505,11 @@ static int __init afiucv_init(void)
24812505
static void __exit afiucv_exit(void)
24822506
{
24832507
if (pr_iucv) {
2484-
device_unregister(af_iucv_dev);
2485-
driver_unregister(&af_iucv_driver);
2486-
pr_iucv->iucv_unregister(&af_iucv_handler, 0);
2508+
afiucv_iucv_exit();
24872509
symbol_put(iucv_if);
2488-
} else
2489-
unregister_netdevice_notifier(&afiucv_netdev_notifier);
2510+
}
2511+
2512+
unregister_netdevice_notifier(&afiucv_netdev_notifier);
24902513
dev_remove_pack(&iucv_packet_type);
24912514
sock_unregister(PF_IUCV);
24922515
proto_unregister(&iucv_proto);

0 commit comments

Comments
 (0)