Skip to content

Commit c7f653e

Browse files
committed
Merge branch 's390-qeth-fixes'
Julian Wiedmann says: ==================== s390/qeth: fixes 2018-06-29 please apply a few qeth fixes for -net and your 4.17 stable queue. Patches 1-3 fix several issues wrt to MAC address management that were introduced during the 4.17 cycle. Patch 4 tackles a long-standing issue with busy multi-connection workloads on devices in af_iucv mode. Patch 5 makes sure to re-enable all active HW offloads, after a card was previously set offline and thus lost its HW context. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents bc800e8 + d025da9 commit c7f653e

File tree

4 files changed

+57
-30
lines changed

4 files changed

+57
-30
lines changed

drivers/s390/net/qeth_core.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,17 @@ struct qeth_trap_id {
829829
/*some helper functions*/
830830
#define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "")
831831

832+
static inline void qeth_scrub_qdio_buffer(struct qdio_buffer *buf,
833+
unsigned int elements)
834+
{
835+
unsigned int i;
836+
837+
for (i = 0; i < elements; i++)
838+
memset(&buf->element[i], 0, sizeof(struct qdio_buffer_element));
839+
buf->element[14].sflags = 0;
840+
buf->element[15].sflags = 0;
841+
}
842+
832843
/**
833844
* qeth_get_elements_for_range() - find number of SBALEs to cover range.
834845
* @start: Start of the address range.
@@ -1029,7 +1040,7 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *,
10291040
__u16, __u16,
10301041
enum qeth_prot_versions);
10311042
int qeth_set_features(struct net_device *, netdev_features_t);
1032-
void qeth_recover_features(struct net_device *dev);
1043+
void qeth_enable_hw_features(struct net_device *dev);
10331044
netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t);
10341045
netdev_features_t qeth_features_check(struct sk_buff *skb,
10351046
struct net_device *dev,

drivers/s390/net/qeth_core_main.c

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,6 @@ static void qeth_notify_skbs(struct qeth_qdio_out_q *queue,
7373
struct qeth_qdio_out_buffer *buf,
7474
enum iucv_tx_notify notification);
7575
static void qeth_release_skbs(struct qeth_qdio_out_buffer *buf);
76-
static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
77-
struct qeth_qdio_out_buffer *buf,
78-
enum qeth_qdio_buffer_states newbufstate);
7976
static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int);
8077

8178
struct workqueue_struct *qeth_wq;
@@ -489,6 +486,7 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
489486
struct qaob *aob;
490487
struct qeth_qdio_out_buffer *buffer;
491488
enum iucv_tx_notify notification;
489+
unsigned int i;
492490

493491
aob = (struct qaob *) phys_to_virt(phys_aob_addr);
494492
QETH_CARD_TEXT(card, 5, "haob");
@@ -513,10 +511,18 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
513511
qeth_notify_skbs(buffer->q, buffer, notification);
514512

515513
buffer->aob = NULL;
516-
qeth_clear_output_buffer(buffer->q, buffer,
517-
QETH_QDIO_BUF_HANDLED_DELAYED);
514+
/* Free dangling allocations. The attached skbs are handled by
515+
* qeth_cleanup_handled_pending().
516+
*/
517+
for (i = 0;
518+
i < aob->sb_count && i < QETH_MAX_BUFFER_ELEMENTS(card);
519+
i++) {
520+
if (aob->sba[i] && buffer->is_header[i])
521+
kmem_cache_free(qeth_core_header_cache,
522+
(void *) aob->sba[i]);
523+
}
524+
atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED);
518525

519-
/* from here on: do not touch buffer anymore */
520526
qdio_release_aob(aob);
521527
}
522528

@@ -3759,6 +3765,10 @@ static void qeth_qdio_output_handler(struct ccw_device *ccwdev,
37593765
QETH_CARD_TEXT(queue->card, 5, "aob");
37603766
QETH_CARD_TEXT_(queue->card, 5, "%lx",
37613767
virt_to_phys(buffer->aob));
3768+
3769+
/* prepare the queue slot for re-use: */
3770+
qeth_scrub_qdio_buffer(buffer->buffer,
3771+
QETH_MAX_BUFFER_ELEMENTS(card));
37623772
if (qeth_init_qdio_out_buf(queue, bidx)) {
37633773
QETH_CARD_TEXT(card, 2, "outofbuf");
37643774
qeth_schedule_recovery(card);
@@ -4834,7 +4844,7 @@ int qeth_vm_request_mac(struct qeth_card *card)
48344844
goto out;
48354845
}
48364846

4837-
ccw_device_get_id(CARD_RDEV(card), &id);
4847+
ccw_device_get_id(CARD_DDEV(card), &id);
48384848
request->resp_buf_len = sizeof(*response);
48394849
request->resp_version = DIAG26C_VERSION2;
48404850
request->op_code = DIAG26C_GET_MAC;
@@ -6459,28 +6469,27 @@ static int qeth_set_ipa_rx_csum(struct qeth_card *card, bool on)
64596469
#define QETH_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_TSO | \
64606470
NETIF_F_IPV6_CSUM)
64616471
/**
6462-
* qeth_recover_features() - Restore device features after recovery
6463-
* @dev: the recovering net_device
6464-
*
6465-
* Caller must hold rtnl lock.
6472+
* qeth_enable_hw_features() - (Re-)Enable HW functions for device features
6473+
* @dev: a net_device
64666474
*/
6467-
void qeth_recover_features(struct net_device *dev)
6475+
void qeth_enable_hw_features(struct net_device *dev)
64686476
{
6469-
netdev_features_t features = dev->features;
64706477
struct qeth_card *card = dev->ml_priv;
6478+
netdev_features_t features;
64716479

6480+
rtnl_lock();
6481+
features = dev->features;
64726482
/* force-off any feature that needs an IPA sequence.
64736483
* netdev_update_features() will restart them.
64746484
*/
64756485
dev->features &= ~QETH_HW_FEATURES;
64766486
netdev_update_features(dev);
6477-
6478-
if (features == dev->features)
6479-
return;
6480-
dev_warn(&card->gdev->dev,
6481-
"Device recovery failed to restore all offload features\n");
6487+
if (features != dev->features)
6488+
dev_warn(&card->gdev->dev,
6489+
"Device recovery failed to restore all offload features\n");
6490+
rtnl_unlock();
64826491
}
6483-
EXPORT_SYMBOL_GPL(qeth_recover_features);
6492+
EXPORT_SYMBOL_GPL(qeth_enable_hw_features);
64846493

64856494
int qeth_set_features(struct net_device *dev, netdev_features_t features)
64866495
{

drivers/s390/net/qeth_l2_main.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac)
140140

141141
static int qeth_l2_write_mac(struct qeth_card *card, u8 *mac)
142142
{
143-
enum qeth_ipa_cmds cmd = is_multicast_ether_addr_64bits(mac) ?
143+
enum qeth_ipa_cmds cmd = is_multicast_ether_addr(mac) ?
144144
IPA_CMD_SETGMAC : IPA_CMD_SETVMAC;
145145
int rc;
146146

@@ -157,7 +157,7 @@ static int qeth_l2_write_mac(struct qeth_card *card, u8 *mac)
157157

158158
static int qeth_l2_remove_mac(struct qeth_card *card, u8 *mac)
159159
{
160-
enum qeth_ipa_cmds cmd = is_multicast_ether_addr_64bits(mac) ?
160+
enum qeth_ipa_cmds cmd = is_multicast_ether_addr(mac) ?
161161
IPA_CMD_DELGMAC : IPA_CMD_DELVMAC;
162162
int rc;
163163

@@ -501,27 +501,34 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
501501
return -ERESTARTSYS;
502502
}
503503

504+
/* avoid racing against concurrent state change: */
505+
if (!mutex_trylock(&card->conf_mutex))
506+
return -EAGAIN;
507+
504508
if (!qeth_card_hw_is_reachable(card)) {
505509
ether_addr_copy(dev->dev_addr, addr->sa_data);
506-
return 0;
510+
goto out_unlock;
507511
}
508512

509513
/* don't register the same address twice */
510514
if (ether_addr_equal_64bits(dev->dev_addr, addr->sa_data) &&
511515
(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
512-
return 0;
516+
goto out_unlock;
513517

514518
/* add the new address, switch over, drop the old */
515519
rc = qeth_l2_send_setmac(card, addr->sa_data);
516520
if (rc)
517-
return rc;
521+
goto out_unlock;
518522
ether_addr_copy(old_addr, dev->dev_addr);
519523
ether_addr_copy(dev->dev_addr, addr->sa_data);
520524

521525
if (card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED)
522526
qeth_l2_remove_mac(card, old_addr);
523527
card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
524-
return 0;
528+
529+
out_unlock:
530+
mutex_unlock(&card->conf_mutex);
531+
return rc;
525532
}
526533

527534
static void qeth_promisc_to_bridge(struct qeth_card *card)
@@ -1112,6 +1119,8 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
11121119
netif_carrier_off(card->dev);
11131120

11141121
qeth_set_allowed_threads(card, 0xffffffff, 0);
1122+
1123+
qeth_enable_hw_features(card->dev);
11151124
if (recover_flag == CARD_STATE_RECOVER) {
11161125
if (recovery_mode &&
11171126
card->info.type != QETH_CARD_TYPE_OSN) {
@@ -1123,9 +1132,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
11231132
}
11241133
/* this also sets saved unicast addresses */
11251134
qeth_l2_set_rx_mode(card->dev);
1126-
rtnl_lock();
1127-
qeth_recover_features(card->dev);
1128-
rtnl_unlock();
11291135
}
11301136
/* let user_space know that device is online */
11311137
kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);

drivers/s390/net/qeth_l3_main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2662,14 +2662,15 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
26622662
netif_carrier_on(card->dev);
26632663
else
26642664
netif_carrier_off(card->dev);
2665+
2666+
qeth_enable_hw_features(card->dev);
26652667
if (recover_flag == CARD_STATE_RECOVER) {
26662668
rtnl_lock();
26672669
if (recovery_mode)
26682670
__qeth_l3_open(card->dev);
26692671
else
26702672
dev_open(card->dev);
26712673
qeth_l3_set_rx_mode(card->dev);
2672-
qeth_recover_features(card->dev);
26732674
rtnl_unlock();
26742675
}
26752676
qeth_trace_features(card);

0 commit comments

Comments
 (0)