Skip to content

Commit

Permalink
Merge branch 's390-qeth-fixes-2021-01-07'
Browse files Browse the repository at this point in the history
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/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
kuba-moo committed Jan 8, 2021
2 parents d708342 + f9c4845 commit 286e95e
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 17 deletions.
3 changes: 2 additions & 1 deletion drivers/s390/net/qeth_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1079,7 +1079,8 @@ struct qeth_card *qeth_get_card_by_busid(char *bus_id);
void qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads,
int clear_start_mask);
int qeth_threads_running(struct qeth_card *, unsigned long);
int qeth_set_offline(struct qeth_card *card, bool resetting);
int qeth_set_offline(struct qeth_card *card, const struct qeth_discipline *disc,
bool resetting);

int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
int (*reply_cb)
Expand Down
38 changes: 25 additions & 13 deletions drivers/s390/net/qeth_core_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5507,12 +5507,12 @@ static int qeth_hardsetup_card(struct qeth_card *card, bool *carrier_ok)
return rc;
}

static int qeth_set_online(struct qeth_card *card)
static int qeth_set_online(struct qeth_card *card,
const struct qeth_discipline *disc)
{
bool carrier_ok;
int rc;

mutex_lock(&card->discipline_mutex);
mutex_lock(&card->conf_mutex);
QETH_CARD_TEXT(card, 2, "setonlin");

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

rc = card->discipline->set_online(card, carrier_ok);
rc = disc->set_online(card, carrier_ok);
if (rc)
goto err_online;

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

mutex_unlock(&card->conf_mutex);
mutex_unlock(&card->discipline_mutex);
return 0;

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

mutex_unlock(&card->conf_mutex);
mutex_unlock(&card->discipline_mutex);
return rc;
}

int qeth_set_offline(struct qeth_card *card, bool resetting)
int qeth_set_offline(struct qeth_card *card, const struct qeth_discipline *disc,
bool resetting)
{
int rc, rc2, rc3;

mutex_lock(&card->discipline_mutex);
mutex_lock(&card->conf_mutex);
QETH_CARD_TEXT(card, 3, "setoffl");

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

cancel_work_sync(&card->rx_mode_work);

card->discipline->set_offline(card);
disc->set_offline(card);

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

mutex_unlock(&card->conf_mutex);
mutex_unlock(&card->discipline_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(qeth_set_offline);

static int qeth_do_reset(void *data)
{
const struct qeth_discipline *disc;
struct qeth_card *card = data;
int rc;

/* Lock-free, other users will block until we are done. */
disc = card->discipline;

QETH_CARD_TEXT(card, 2, "recover1");
if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD))
return 0;
QETH_CARD_TEXT(card, 2, "recover2");
dev_warn(&card->gdev->dev,
"A recovery process has been started for the device\n");

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

QETH_CARD_TEXT(card, 2, "removedv");

mutex_lock(&card->discipline_mutex);
if (card->discipline) {
card->discipline->remove(gdev);
qeth_core_free_discipline(card);
}
mutex_unlock(&card->discipline_mutex);

qeth_free_qdio_queues(card);

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

mutex_lock(&card->discipline_mutex);
if (!card->discipline) {
def_discipline = IS_IQD(card) ? QETH_DISCIPLINE_LAYER3 :
QETH_DISCIPLINE_LAYER2;
Expand All @@ -6647,16 +6652,23 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev)
}
}

rc = qeth_set_online(card);
rc = qeth_set_online(card, card->discipline);

err:
mutex_unlock(&card->discipline_mutex);
return rc;
}

static int qeth_core_set_offline(struct ccwgroup_device *gdev)
{
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
int rc;

return qeth_set_offline(card, false);
mutex_lock(&card->discipline_mutex);
rc = qeth_set_offline(card, card->discipline, false);
mutex_unlock(&card->discipline_mutex);

return rc;
}

static void qeth_core_shutdown(struct ccwgroup_device *gdev)
Expand Down
2 changes: 1 addition & 1 deletion drivers/s390/net/qeth_l2_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2208,7 +2208,7 @@ static void qeth_l2_remove_device(struct ccwgroup_device *gdev)
wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);

if (gdev->state == CCWGROUP_ONLINE)
qeth_set_offline(card, false);
qeth_set_offline(card, card->discipline, false);

cancel_work_sync(&card->close_dev_work);
if (card->dev->reg_state == NETREG_REGISTERED)
Expand Down
4 changes: 2 additions & 2 deletions drivers/s390/net/qeth_l3_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1813,7 +1813,7 @@ static netdev_features_t qeth_l3_osa_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
{
if (qeth_get_ip_version(skb) != 4)
if (vlan_get_protocol(skb) != htons(ETH_P_IP))
features &= ~NETIF_F_HW_VLAN_CTAG_TX;
return qeth_features_check(skb, dev, features);
}
Expand Down Expand Up @@ -1971,7 +1971,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);

if (cgdev->state == CCWGROUP_ONLINE)
qeth_set_offline(card, false);
qeth_set_offline(card, card->discipline, false);

cancel_work_sync(&card->close_dev_work);
if (card->dev->reg_state == NETREG_REGISTERED)
Expand Down

0 comments on commit 286e95e

Please sign in to comment.