Skip to content

Commit 286e95e

Browse files
committed
Merge branch 's390-qeth-fixes-2021-01-07'
Julian Wiedmann says: ==================== s390/qeth: fixes 2021-01-07 This brings two locking fixes for the device control path. Also one fix for a path where our .ndo_features_check() attempts to access a non-existent L2 header. ==================== Link: https://lore.kernel.org/r/20210107172442.1737-1-jwi@linux.ibm.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents d708342 + f9c4845 commit 286e95e

File tree

4 files changed

+30
-17
lines changed

4 files changed

+30
-17
lines changed

drivers/s390/net/qeth_core.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,8 @@ struct qeth_card *qeth_get_card_by_busid(char *bus_id);
10791079
void qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads,
10801080
int clear_start_mask);
10811081
int qeth_threads_running(struct qeth_card *, unsigned long);
1082-
int qeth_set_offline(struct qeth_card *card, bool resetting);
1082+
int qeth_set_offline(struct qeth_card *card, const struct qeth_discipline *disc,
1083+
bool resetting);
10831084

10841085
int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
10851086
int (*reply_cb)

drivers/s390/net/qeth_core_main.c

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5507,12 +5507,12 @@ static int qeth_hardsetup_card(struct qeth_card *card, bool *carrier_ok)
55075507
return rc;
55085508
}
55095509

5510-
static int qeth_set_online(struct qeth_card *card)
5510+
static int qeth_set_online(struct qeth_card *card,
5511+
const struct qeth_discipline *disc)
55115512
{
55125513
bool carrier_ok;
55135514
int rc;
55145515

5515-
mutex_lock(&card->discipline_mutex);
55165516
mutex_lock(&card->conf_mutex);
55175517
QETH_CARD_TEXT(card, 2, "setonlin");
55185518

@@ -5529,15 +5529,14 @@ static int qeth_set_online(struct qeth_card *card)
55295529
/* no need for locking / error handling at this early stage: */
55305530
qeth_set_real_num_tx_queues(card, qeth_tx_actual_queues(card));
55315531

5532-
rc = card->discipline->set_online(card, carrier_ok);
5532+
rc = disc->set_online(card, carrier_ok);
55335533
if (rc)
55345534
goto err_online;
55355535

55365536
/* let user_space know that device is online */
55375537
kobject_uevent(&card->gdev->dev.kobj, KOBJ_CHANGE);
55385538

55395539
mutex_unlock(&card->conf_mutex);
5540-
mutex_unlock(&card->discipline_mutex);
55415540
return 0;
55425541

55435542
err_online:
@@ -5552,15 +5551,14 @@ static int qeth_set_online(struct qeth_card *card)
55525551
qdio_free(CARD_DDEV(card));
55535552

55545553
mutex_unlock(&card->conf_mutex);
5555-
mutex_unlock(&card->discipline_mutex);
55565554
return rc;
55575555
}
55585556

5559-
int qeth_set_offline(struct qeth_card *card, bool resetting)
5557+
int qeth_set_offline(struct qeth_card *card, const struct qeth_discipline *disc,
5558+
bool resetting)
55605559
{
55615560
int rc, rc2, rc3;
55625561

5563-
mutex_lock(&card->discipline_mutex);
55645562
mutex_lock(&card->conf_mutex);
55655563
QETH_CARD_TEXT(card, 3, "setoffl");
55665564

@@ -5581,7 +5579,7 @@ int qeth_set_offline(struct qeth_card *card, bool resetting)
55815579

55825580
cancel_work_sync(&card->rx_mode_work);
55835581

5584-
card->discipline->set_offline(card);
5582+
disc->set_offline(card);
55855583

55865584
qeth_qdio_clear_card(card, 0);
55875585
qeth_drain_output_queues(card);
@@ -5602,25 +5600,28 @@ int qeth_set_offline(struct qeth_card *card, bool resetting)
56025600
kobject_uevent(&card->gdev->dev.kobj, KOBJ_CHANGE);
56035601

56045602
mutex_unlock(&card->conf_mutex);
5605-
mutex_unlock(&card->discipline_mutex);
56065603
return 0;
56075604
}
56085605
EXPORT_SYMBOL_GPL(qeth_set_offline);
56095606

56105607
static int qeth_do_reset(void *data)
56115608
{
5609+
const struct qeth_discipline *disc;
56125610
struct qeth_card *card = data;
56135611
int rc;
56145612

5613+
/* Lock-free, other users will block until we are done. */
5614+
disc = card->discipline;
5615+
56155616
QETH_CARD_TEXT(card, 2, "recover1");
56165617
if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD))
56175618
return 0;
56185619
QETH_CARD_TEXT(card, 2, "recover2");
56195620
dev_warn(&card->gdev->dev,
56205621
"A recovery process has been started for the device\n");
56215622

5622-
qeth_set_offline(card, true);
5623-
rc = qeth_set_online(card);
5623+
qeth_set_offline(card, disc, true);
5624+
rc = qeth_set_online(card, disc);
56245625
if (!rc) {
56255626
dev_info(&card->gdev->dev,
56265627
"Device successfully recovered!\n");
@@ -6584,6 +6585,7 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
65846585
break;
65856586
default:
65866587
card->info.layer_enforced = true;
6588+
/* It's so early that we don't need the discipline_mutex yet. */
65876589
rc = qeth_core_load_discipline(card, enforced_disc);
65886590
if (rc)
65896591
goto err_load;
@@ -6616,10 +6618,12 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev)
66166618

66176619
QETH_CARD_TEXT(card, 2, "removedv");
66186620

6621+
mutex_lock(&card->discipline_mutex);
66196622
if (card->discipline) {
66206623
card->discipline->remove(gdev);
66216624
qeth_core_free_discipline(card);
66226625
}
6626+
mutex_unlock(&card->discipline_mutex);
66236627

66246628
qeth_free_qdio_queues(card);
66256629

@@ -6634,6 +6638,7 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev)
66346638
int rc = 0;
66356639
enum qeth_discipline_id def_discipline;
66366640

6641+
mutex_lock(&card->discipline_mutex);
66376642
if (!card->discipline) {
66386643
def_discipline = IS_IQD(card) ? QETH_DISCIPLINE_LAYER3 :
66396644
QETH_DISCIPLINE_LAYER2;
@@ -6647,16 +6652,23 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev)
66476652
}
66486653
}
66496654

6650-
rc = qeth_set_online(card);
6655+
rc = qeth_set_online(card, card->discipline);
6656+
66516657
err:
6658+
mutex_unlock(&card->discipline_mutex);
66526659
return rc;
66536660
}
66546661

66556662
static int qeth_core_set_offline(struct ccwgroup_device *gdev)
66566663
{
66576664
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
6665+
int rc;
66586666

6659-
return qeth_set_offline(card, false);
6667+
mutex_lock(&card->discipline_mutex);
6668+
rc = qeth_set_offline(card, card->discipline, false);
6669+
mutex_unlock(&card->discipline_mutex);
6670+
6671+
return rc;
66606672
}
66616673

66626674
static void qeth_core_shutdown(struct ccwgroup_device *gdev)

drivers/s390/net/qeth_l2_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2208,7 +2208,7 @@ static void qeth_l2_remove_device(struct ccwgroup_device *gdev)
22082208
wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
22092209

22102210
if (gdev->state == CCWGROUP_ONLINE)
2211-
qeth_set_offline(card, false);
2211+
qeth_set_offline(card, card->discipline, false);
22122212

22132213
cancel_work_sync(&card->close_dev_work);
22142214
if (card->dev->reg_state == NETREG_REGISTERED)

drivers/s390/net/qeth_l3_main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,7 +1813,7 @@ static netdev_features_t qeth_l3_osa_features_check(struct sk_buff *skb,
18131813
struct net_device *dev,
18141814
netdev_features_t features)
18151815
{
1816-
if (qeth_get_ip_version(skb) != 4)
1816+
if (vlan_get_protocol(skb) != htons(ETH_P_IP))
18171817
features &= ~NETIF_F_HW_VLAN_CTAG_TX;
18181818
return qeth_features_check(skb, dev, features);
18191819
}
@@ -1971,7 +1971,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
19711971
wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
19721972

19731973
if (cgdev->state == CCWGROUP_ONLINE)
1974-
qeth_set_offline(card, false);
1974+
qeth_set_offline(card, card->discipline, false);
19751975

19761976
cancel_work_sync(&card->close_dev_work);
19771977
if (card->dev->reg_state == NETREG_REGISTERED)

0 commit comments

Comments
 (0)