s390/qeth: fixes 2018-04-19
Subsystems (4)
cover s390/qeth: fixes 2018-04-19
Hi Dave,
new mail address, same old me.
Please apply the following qeth fixes for 4.17. The common theme seems to be error handling improvements in various areas of cmd IO.
Patches 1-3 should also go back to stable.
Thank you,
Julian
Julian Wiedmann (6):
s390/qeth: fix error handling in adapter command callbacks s390/qeth: avoid control IO completion stalls s390/qeth: handle failure on workqueue creation s390/qeth: fix MAC address update sequence s390/qeth: fix request-side race during cmd IO timeout s390/qeth: use Read device to query hypervisor for MAC
drivers/s390/net/qeth_core.h | 2 - drivers/s390/net/qeth_core_main.c | 158 +++++++++++++++++--------------------- drivers/s390/net/qeth_core_mpc.h | 12 +++ drivers/s390/net/qeth_l2_main.c | 59 +++++++------- 4 files changed, 116 insertions(+), 115 deletions(-)
Signature · 1 line
2.13.5
PATCH 1/6 s390/qeth: fix error handling in adapter command callbacks
From: Julian Wiedmann <[email protected]>
Make sure to check both return code fields before(!) processing the command response. Otherwise we risk operating on invalid data.
This matches an earlier fix for SETASSPARMS commands, see
commit ad3cbf613329 ("s390/qeth: fix error handling in checksum cmd callback").
--- drivers/s390/net/qeth_core_main.c | 85 +++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 48 deletions(-)
drivers/s390/net/qeth_core_main.c +37 -48
@@ -3033,28 +3033,23 @@ static int qeth_send_startlan(struct qeth_card *card)return rc; } -static int qeth_default_setadapterparms_cb (struct qeth_card *card, -struct qeth_reply *reply,unsigned long data) +static int qeth_setadpparms_inspect_rc (struct qeth_ipa_cmd *cmd) { -struct qeth_ipa_cmd *cmd; - -QETH_CARD_TEXT (card,4 ,"defadpcb" ); - - cmd = (struct qeth_ipa_cmd *) data; -if (cmd->hdr.return_code ==0 ) +if (!cmd->hdr.return_code) cmd->hdr.return_code = cmd->data.setadapterparms.hdr.return_code; -return 0 ; +return cmd->hdr.return_code; }static int qeth_query_setadapterparms_cb (struct qeth_card *card,struct qeth_reply *reply,unsigned long data) { -struct qeth_ipa_cmd *cmd; +struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;QETH_CARD_TEXT (card,3 ,"quyadpcb" ); +if (qeth_setadpparms_inspect_rc (cmd)) +return 0 ; - cmd = (struct qeth_ipa_cmd *) data;if (cmd->data.setadapterparms.data.query_cmds_supp.lan_type &0x7f ) { card->info.link_type = cmd->data.setadapterparms.data.query_cmds_supp.lan_type;
@@ -3062,7 +3057,7 @@ static int qeth_query_setadapterparms_cb(struct qeth_card *card, } card->options.adp.supported_funcs = cmd->data.setadapterparms.data.query_cmds_supp.supported_cmds; -return qeth_default_setadapterparms_cb (card, reply, (unsigned long )cmd); +return 0 ; } static struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card,
@@ -3154,22 +3149,20 @@ EXPORT_SYMBOL_GPL(qeth_query_ipassists);static int qeth_query_switch_attributes_cb (struct qeth_card *card,struct qeth_reply *reply,unsigned long data) { -struct qeth_ipa_cmd *cmd; -struct qeth_switch_info *sw_info; +struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;struct qeth_query_switch_attributes *attrs; +struct qeth_switch_info *sw_info;QETH_CARD_TEXT (card,2 ,"qswiatcb" ); - cmd = (struct qeth_ipa_cmd *) data; - sw_info = (struct qeth_switch_info *)reply->param; -if (cmd->data.setadapterparms.hdr.return_code ==0 ) { - attrs = &cmd->data.setadapterparms.data.query_switch_attributes; - sw_info->capabilities = attrs->capabilities; - sw_info->settings = attrs->settings; -QETH_CARD_TEXT_ (card,2 ,"%04x%04x" , sw_info->capabilities, - sw_info->settings); - } -qeth_default_setadapterparms_cb (card, reply, (unsigned long ) cmd); +if (qeth_setadpparms_inspect_rc (cmd)) +return 0 ; + sw_info = (struct qeth_switch_info *)reply->param; + attrs = &cmd->data.setadapterparms.data.query_switch_attributes; + sw_info->capabilities = attrs->capabilities; + sw_info->settings = attrs->settings; +QETH_CARD_TEXT_ (card,2 ,"%04x%04x" , sw_info->capabilities, + sw_info->settings);return 0 ; }
@@ -4207,16 +4200,13 @@ EXPORT_SYMBOL_GPL(qeth_do_send_packet);static int qeth_setadp_promisc_mode_cb (struct qeth_card *card,struct qeth_reply *reply,unsigned long data) { -struct qeth_ipa_cmd *cmd; +struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;struct qeth_ipacmd_setadpparms *setparms;QETH_CARD_TEXT (card,4 ,"prmadpcb" ); - cmd = (struct qeth_ipa_cmd *) data; setparms = &(cmd->data.setadapterparms); - -qeth_default_setadapterparms_cb (card, reply, (unsigned long )cmd); -if (cmd->hdr.return_code) { +if (qeth_setadpparms_inspect_rc (cmd)) {QETH_CARD_TEXT_ (card,4 ,"prmrc%x" , cmd->hdr.return_code); setparms->data.mode =SET_PROMISC_MODE_OFF ; }
@@ -4286,18 +4276,18 @@ EXPORT_SYMBOL_GPL(qeth_get_stats);static int qeth_setadpparms_change_macaddr_cb (struct qeth_card *card,struct qeth_reply *reply,unsigned long data) { -struct qeth_ipa_cmd *cmd; +struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;QETH_CARD_TEXT (card,4 ,"chgmaccb" ); +if (qeth_setadpparms_inspect_rc (cmd)) +return 0 ; - cmd = (struct qeth_ipa_cmd *) data;if (!card->options.layer2 || !(card->info.mac_bits &QETH_LAYER2_MAC_READ )) {ether_addr_copy (card->dev->dev_addr, cmd->data.setadapterparms.data.change_addr.addr); card->info.mac_bits |=QETH_LAYER2_MAC_READ ; } -qeth_default_setadapterparms_cb (card, reply, (unsigned long ) cmd);return 0 ; }
@@ -4328,13 +4318,15 @@ EXPORT_SYMBOL_GPL(qeth_setadpparms_change_macaddr);static int qeth_setadpparms_set_access_ctrl_cb (struct qeth_card *card,struct qeth_reply *reply,unsigned long data) { -struct qeth_ipa_cmd *cmd; +struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;struct qeth_set_access_ctrl *access_ctrl_req;int fallback = *(int *)reply->param;QETH_CARD_TEXT (card,4 ,"setaccb" ); +if (cmd->hdr.return_code) +return 0 ; +qeth_setadpparms_inspect_rc (cmd); - cmd = (struct qeth_ipa_cmd *) data; access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;QETH_DBF_TEXT_ (SETUP ,2 ,"setaccb" );QETH_DBF_TEXT_ (SETUP ,2 ,"%s" , card->gdev->dev.kobj.name);
@@ -4407,7 +4399,6 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card, card->options.isolation = card->options.prev_isolation;break ; } -qeth_default_setadapterparms_cb (card, reply, (unsigned long ) cmd);return 0 ; }
@@ -4695,14 +4686,15 @@ static int qeth_snmp_command(struct qeth_card *card, char __user *udata)static int qeth_setadpparms_query_oat_cb (struct qeth_card *card,struct qeth_reply *reply,unsigned long data) { -struct qeth_ipa_cmd *cmd; +struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *)data;struct qeth_qoat_priv *priv;char *resdata;int resdatalen;QETH_CARD_TEXT (card,3 ,"qoatcb" ); +if (qeth_setadpparms_inspect_rc (cmd)) +return 0 ; - cmd = (struct qeth_ipa_cmd *)data; priv = (struct qeth_qoat_priv *)reply->param; resdatalen = cmd->data.setadapterparms.hdr.cmdlength; resdata = (char *)data +28 ;
@@ -4796,21 +4788,18 @@ static int qeth_query_oat_command(struct qeth_card *card, char __user *udata)static int qeth_query_card_info_cb (struct qeth_card *card,struct qeth_reply *reply,unsigned long data) { -struct qeth_ipa_cmd *cmd; +struct carrier_info *carrier_info = (struct carrier_info *)reply->param; +struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *)data;struct qeth_query_card_info *card_info; -struct carrier_info *carrier_info;QETH_CARD_TEXT (card,2 ,"qcrdincb" ); - carrier_info = (struct carrier_info *)reply->param; - cmd = (struct qeth_ipa_cmd *)data; - card_info = &cmd->data.setadapterparms.data.card_info; -if (cmd->data.setadapterparms.hdr.return_code ==0 ) { - carrier_info->card_type = card_info->card_type; - carrier_info->port_mode = card_info->port_mode; - carrier_info->port_speed = card_info->port_speed; - } +if (qeth_setadpparms_inspect_rc (cmd)) +return 0 ; -qeth_default_setadapterparms_cb (card, reply, (unsigned long ) cmd); + card_info = &cmd->data.setadapterparms.data.card_info; + carrier_info->card_type = card_info->card_type; + carrier_info->port_mode = card_info->port_mode; + carrier_info->port_speed = card_info->port_speed;return 0 ; }
Signature · 1 line
2.13.5
PATCH 2/6 s390/qeth: avoid control IO completion stalls
In reply to Julian WiedmannFrom: Julian Wiedmann <[email protected]>
For control IO, qeth currently tracks the index of the buffer that it expects to complete the next IO on each qeth_channel. If the channel presents an IRQ while this buffer has not yet completed, no completion processing for _any_ completed buffer takes place.
So if the 'next buffer' is skipped for any sort of reason* (eg. when it is released due to error conditions, before the IO is started), the buffer obviously won't switch to PROCESSED until it is eventually allocated for a _different_ IO and completes.
Until this happens, all completion processing on that channel stalls and pending requests possibly time out.
As a fix, remove the whole 'next buffer' logic and simply process any IO buffer right when it completes. A channel will never have more than one IO pending, so there's no risk of processing out-of-sequence.
*Note: currently just one location in the code really handles this problem,
by advancing the 'next' index manually.
--- drivers/s390/net/qeth_core.h | 2 -- drivers/s390/net/qeth_core_main.c | 22 +++++----------------- 2 files changed, 5 insertions(+), 19 deletions(-)
drivers/s390/net/qeth_core.h +0 -2
@@ -557,7 +557,6 @@ enum qeth_prot_versions {enum qeth_cmd_buffer_state {BUF_STATE_FREE ,BUF_STATE_LOCKED , -BUF_STATE_PROCESSED , };enum qeth_cq {
@@ -601,7 +600,6 @@ struct qeth_channel {struct qeth_cmd_buffer iob[QETH_CMD_BUFFER_NO ];atomic_t irq_pending;int io_buf_no; -int buf_no; };/**
drivers/s390/net/qeth_core_main.c +5 -17
@@ -818,7 +818,6 @@ void qeth_clear_cmd_buffers(struct qeth_channel *channel)for (cnt =0 ; cnt <QETH_CMD_BUFFER_NO ; cnt++)qeth_release_buffer (channel, &channel->iob[cnt]); - channel->buf_no =0 ; channel->io_buf_no =0 ; }EXPORT_SYMBOL_GPL (qeth_clear_cmd_buffers);
@@ -924,7 +923,6 @@ static int qeth_setup_channel(struct qeth_channel *channel)kfree (channel->iob[cnt].data);return -ENOMEM ; } - channel->buf_no =0 ; channel->io_buf_no =0 ;atomic_set (&channel->irq_pending,0 );spin_lock_init (&channel->iob_lock);
@@ -1100,11 +1098,9 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, {int rc;int cstat, dstat; -struct qeth_cmd_buffer *buffer;struct qeth_channel *channel;struct qeth_card *card;struct qeth_cmd_buffer *iob; -__u8 index;if (__qeth_check_irb_error (cdev, intparm, irb))return ;
@@ -1182,25 +1178,18 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, channel->state =CH_STATE_RCD_DONE ; goto out; } -if (intparm) { - buffer = (struct qeth_cmd_buffer *)__va ((addr_t )intparm); - buffer->state =BUF_STATE_PROCESSED ; - }if (channel == &card->data)return ;if (channel == &card->read && channel->state ==CH_STATE_UP )__qeth_issue_next_read (card); - iob = channel->iob; - index = channel->buf_no; -while (iob[index].state ==BUF_STATE_PROCESSED ) { -if (iob[index].callback !=NULL ) - iob[index].callback (channel, iob + index); - - index = (index +1 ) %QETH_CMD_BUFFER_NO ; +if (intparm) { + iob = (struct qeth_cmd_buffer *)__va ((addr_t )intparm); +if (iob->callback) + iob->callback (iob->channel, iob); } - channel->buf_no = index; + out:wake_up (&card->wait_q);return ;
@@ -2214,7 +2203,6 @@ int qeth_send_control_data(struct qeth_card *card, int len, error:atomic_set (&card->write.irq_pending,0 );qeth_release_buffer (iob->channel, iob); - card->write.buf_no = (card->write.buf_no +1 ) %QETH_CMD_BUFFER_NO ; rc = reply->rc;qeth_put_reply (reply);return rc;
Signature · 1 line
2.13.5
PATCH 3/6 s390/qeth: handle failure on workqueue creation
In reply to Julian WiedmannCreating the global workqueue during driver init may fail, deal with it. Also, destroy the created workqueue on any subsequent error.
--- drivers/s390/net/qeth_core_main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/s390/net/qeth_core_main.c +7 -1
@@ -6540,10 +6540,14 @@ static int __init qeth_core_init(void)mutex_init (&qeth_mod_mutex); qeth_wq =create_singlethread_workqueue ("qeth_wq" ); +if (!qeth_wq) { + rc = -ENOMEM ; + goto out_err; + } rc =qeth_register_dbf_views ();if (rc) - goto out_err; + goto dbf_err; qeth_core_root_dev =root_device_register ("qeth" ); rc =PTR_ERR_OR_ZERO (qeth_core_root_dev);if (rc)
@@ -6580,6 +6584,8 @@ static int __init qeth_core_init(void)root_device_unregister (qeth_core_root_dev); register_err:qeth_unregister_dbf_views (); +dbf_err: +destroy_workqueue (qeth_wq); out_err:pr_err ("Initializing the qeth device driver failed\n" );return rc;
Signature · 1 line
2.13.5
PATCH 4/6 s390/qeth: fix MAC address update sequence
In reply to Julian WiedmannFrom: Julian Wiedmann <[email protected]>
When changing the MAC address on a L2 qeth device, current code first unregisters the old address, then registers the new one.
If HW rejects the new address (or the IO fails), the device ends up with no operable address at all.
Re-order the code flow so that the old address only gets dropped if the new address was registered successfully. While at it, add logic to catch some corner-cases.
--- drivers/s390/net/qeth_l2_main.c | 55 +++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 24 deletions(-)
drivers/s390/net/qeth_l2_main.c +31 -24
@@ -122,13 +122,10 @@ static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac)QETH_CARD_TEXT (card,2 ,"L2Setmac" ); rc =qeth_l2_send_setdelmac (card, mac,IPA_CMD_SETVMAC );if (rc ==0 ) { - card->info.mac_bits |=QETH_LAYER2_MAC_REGISTERED ; -ether_addr_copy (card->dev->dev_addr, mac);dev_info (&card->gdev->dev, -"MAC address %pM successfully registered on device %s\n" , - card->dev->dev_addr, card->dev->name); +"MAC address %pM successfully registered on device %s\n" , + mac, card->dev->name); }else { - card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED ;switch (rc) {case -EEXIST : dev_warn(&card->gdev->dev,
@@ -143,19 +140,6 @@ static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac)return rc; } -static int qeth_l2_send_delmac (struct qeth_card *card,__u8 *mac) -{ -int rc; - -QETH_CARD_TEXT (card,2 ,"L2Delmac" ); -if (!(card->info.mac_bits &QETH_LAYER2_MAC_REGISTERED )) -return 0 ; - rc =qeth_l2_send_setdelmac (card, mac,IPA_CMD_DELVMAC ); -if (rc ==0 ) - card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED ; -return rc; -} -static int qeth_l2_write_mac (struct qeth_card *card,u8 *mac) { enum qeth_ipa_cmds cmd = is_multicast_ether_addr_64bits(mac) ?
@@ -520,6 +504,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) {struct sockaddr *addr = p;struct qeth_card *card = dev->ml_priv; +u8 old_addr[ETH_ALEN ];int rc =0 ;QETH_CARD_TEXT (card,3 ,"setmac" );
@@ -531,14 +516,35 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)return -EOPNOTSUPP ; }QETH_CARD_HEX (card,3 , addr->sa_data,ETH_ALEN ); +if (!is_valid_ether_addr (addr->sa_data)) +return -EADDRNOTAVAIL ; +if (qeth_wait_for_threads (card,QETH_RECOVER_THREAD )) {QETH_CARD_TEXT (card,3 ,"setmcREC" );return -ERESTARTSYS ; } - rc =qeth_l2_send_delmac (card, &card->dev->dev_addr[0 ]); -if (!rc || (rc == -ENOENT )) - rc =qeth_l2_send_setmac (card, addr->sa_data); -return rc ? -EINVAL :0 ; + +if (!qeth_card_hw_is_reachable (card)) { +ether_addr_copy (dev->dev_addr, addr->sa_data); +return 0 ; + } + +/* don't register the same address twice */ +if (ether_addr_equal_64bits (dev->dev_addr, addr->sa_data) && + (card->info.mac_bits &QETH_LAYER2_MAC_REGISTERED )) +return 0 ; + +/* add the new address, switch over, drop the old */ + rc =qeth_l2_send_setmac (card, addr->sa_data); +if (rc) +return rc; +ether_addr_copy (old_addr, dev->dev_addr); +ether_addr_copy (dev->dev_addr, addr->sa_data); + +if (card->info.mac_bits &QETH_LAYER2_MAC_REGISTERED ) +qeth_l2_remove_mac (card, old_addr); + card->info.mac_bits |=QETH_LAYER2_MAC_REGISTERED ; +return 0 ; }static void qeth_promisc_to_bridge (struct qeth_card *card)
@@ -1068,8 +1074,9 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) goto out_remove; } -if (card->info.type !=QETH_CARD_TYPE_OSN ) -qeth_l2_send_setmac (card, &card->dev->dev_addr[0 ]); +if (card->info.type !=QETH_CARD_TYPE_OSN && + !qeth_l2_send_setmac (card, card->dev->dev_addr)) + card->info.mac_bits |=QETH_LAYER2_MAC_REGISTERED ;if (qeth_is_diagass_supported (card,QETH_DIAGS_CMD_TRAP )) { if (card->info.hwtrap &&
Signature · 1 line
2.13.5
PATCH 5/6 s390/qeth: fix request-side race during cmd IO timeout
In reply to Julian WiedmannFrom: Julian Wiedmann <[email protected]>
Submitting a cmd IO request (usually on the WRITE device, but for IDX also on the READ device) is currently done with ccw_device_start() and a manual timeout in the caller.
On timeout, the caller cleans up the related resources (eg. IO buffer). But 1) the IO might still be active and utilize those resources, and
2) when the IO completes, qeth_irq() will attempt to clean up the same resources again.
Instead of introducing additional resource locking, switch to ccw_device_start_timeout() to ensure IO termination after timeout, and let the IRQ handler alone deal with cleaning up after a request.
This also removes a stray write->irq_pending reset from clear_ipacmd_list(). The routine doesn't terminate any pending IO on the WRITE device, so this should be handled properly via IO timeout in the IRQ handler.
--- drivers/s390/net/qeth_core_main.c | 51 ++++++++++++++++++++------------------- drivers/s390/net/qeth_core_mpc.h | 12 +++++++++ drivers/s390/net/qeth_l2_main.c | 4 +-- 3 files changed, 40 insertions(+), 27 deletions(-)
drivers/s390/net/qeth_core_main.c +26 -25
@@ -706,7 +706,6 @@ void qeth_clear_ipacmd_list(struct qeth_card *card)qeth_put_reply (reply); }spin_unlock_irqrestore (&card->lock, flags); -atomic_set (&card->write.irq_pending,0 ); }EXPORT_SYMBOL_GPL (qeth_clear_ipacmd_list);
@@ -1098,14 +1097,9 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, {int rc;int cstat, dstat; +struct qeth_cmd_buffer *iob =NULL ;struct qeth_channel *channel;struct qeth_card *card; -struct qeth_cmd_buffer *iob; - -if (__qeth_check_irb_error (cdev, intparm, irb)) -return ; - cstat = irb->scsw.cmd.cstat; - dstat = irb->scsw.cmd.dstat; card =CARD_FROM_CDEV (cdev);if (!card)
@@ -1123,6 +1117,19 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, channel = &card->data;QETH_CARD_TEXT (card,5 ,"data" ); } + +if (qeth_intparm_is_iob (intparm)) + iob = (struct qeth_cmd_buffer *)__va ((addr_t )intparm); + +if (__qeth_check_irb_error (cdev, intparm, irb)) { +/* IO was terminated, free its resources. */ +if (iob) +qeth_release_buffer (iob->channel, iob); +atomic_set (&channel->irq_pending,0 ); +wake_up (&card->wait_q); +return ; + } +atomic_set (&channel->irq_pending,0 );if (irb->scsw.cmd.fctl & (SCSW_FCTL_CLEAR_FUNC ))
@@ -1146,6 +1153,10 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,/* we don't have to handle this further */ intparm =0 ; } + + cstat = irb->scsw.cmd.cstat; + dstat = irb->scsw.cmd.dstat; +if ((dstat &DEV_STAT_UNIT_EXCEP ) || (dstat &DEV_STAT_UNIT_CHECK ) || (cstat)) {
@@ -1184,11 +1195,8 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, channel->state == CH_STATE_UP)__qeth_issue_next_read (card); -if (intparm) { - iob = (struct qeth_cmd_buffer *)__va ((addr_t )intparm); -if (iob->callback) - iob->callback (iob->channel, iob); - } +if (iob && iob->callback) + iob->callback (iob->channel, iob); out:wake_up (&card->wait_q);
@@ -1859,8 +1867,8 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel, atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);QETH_DBF_TEXT (SETUP ,6 ,"noirqpnd" );spin_lock_irqsave (get_ccwdev_lock (channel->ccwdev), flags); - rc =ccw_device_start (channel->ccwdev, - &channel->ccw, (addr_t ) iob,0 ,0 ); + rc =ccw_device_start_timeout (channel->ccwdev, &channel->ccw, + (addr_t ) iob,0 ,0 ,QETH_TIMEOUT );spin_unlock_irqrestore (get_ccwdev_lock (channel->ccwdev), flags);if (rc) {
@@ -1877,7 +1885,6 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel,if (channel->state !=CH_STATE_UP ) { rc = -ETIME ;QETH_DBF_TEXT_ (SETUP ,2 ,"3err%d" , rc); -qeth_clear_cmd_buffers (channel); }else rc =0 ;return rc;
@@ -1931,8 +1938,8 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);QETH_DBF_TEXT (SETUP ,6 ,"noirqpnd" );spin_lock_irqsave (get_ccwdev_lock (channel->ccwdev), flags); - rc =ccw_device_start (channel->ccwdev, - &channel->ccw, (addr_t ) iob,0 ,0 ); + rc =ccw_device_start_timeout (channel->ccwdev, &channel->ccw, + (addr_t ) iob,0 ,0 ,QETH_TIMEOUT );spin_unlock_irqrestore (get_ccwdev_lock (channel->ccwdev), flags);if (rc) {
@@ -1953,7 +1960,6 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel,QETH_DBF_MESSAGE (2 ,"%s IDX activate timed out\n" ,dev_name (&channel->ccwdev->dev));QETH_DBF_TEXT_ (SETUP ,2 ,"2err%d" , -ETIME ); -qeth_clear_cmd_buffers (channel);return -ETIME ; }return qeth_idx_activate_get_answer (channel, idx_reply_cb);
@@ -2155,8 +2161,8 @@ int qeth_send_control_data(struct qeth_card *card, int len,QETH_CARD_TEXT (card,6 ,"noirqpnd" );spin_lock_irqsave (get_ccwdev_lock (card->write.ccwdev), flags); - rc =ccw_device_start (card->write.ccwdev, &card->write.ccw, - (addr_t ) iob,0 ,0 ); + rc =ccw_device_start_timeout (CARD_WDEV (card), &card->write.ccw, + (addr_t ) iob,0 ,0 , event_timeout);spin_unlock_irqrestore (get_ccwdev_lock (card->write.ccwdev), flags);if (rc) { QETH_DBF_MESSAGE(2, "%s qeth_send_control_data: "
@@ -2188,8 +2194,6 @@ int qeth_send_control_data(struct qeth_card *card, int len, } } -if (reply->rc == -EIO ) - goto error; rc = reply->rc;qeth_put_reply (reply);return rc;
@@ -2200,9 +2204,6 @@ int qeth_send_control_data(struct qeth_card *card, int len,list_del_init (&reply->list);spin_unlock_irqrestore (&reply->card->lock, flags);atomic_inc (&reply->received); -error: -atomic_set (&card->write.irq_pending,0 ); -qeth_release_buffer (iob->channel, iob); rc = reply->rc;qeth_put_reply (reply);return rc;
drivers/s390/net/qeth_core_mpc.h +12 -0
@@ -35,6 +35,18 @@ extern unsigned char IPA_PDU_HEADER[];#define QETH_HALT_CHANNEL_PARM -11#define QETH_RCD_PARM -12 +static inline bool qeth_intparm_is_iob (unsigned long intparm) +{ +switch (intparm) { +case QETH_CLEAR_CHANNEL_PARM : +case QETH_HALT_CHANNEL_PARM : +case QETH_RCD_PARM : +case 0 : +return false; + } +return true; +} +/*****************************************************************************/ /* IP Assist related definitions */ /*****************************************************************************/
drivers/s390/net/qeth_l2_main.c +2 -2
@@ -1346,8 +1346,8 @@ static int qeth_osn_send_control_data(struct qeth_card *card, int len,qeth_prepare_control_data (card, len, iob);QETH_CARD_TEXT (card,6 ,"osnoirqp" );spin_lock_irqsave (get_ccwdev_lock (card->write.ccwdev), flags); - rc =ccw_device_start (card->write.ccwdev, &card->write.ccw, - (addr_t ) iob,0 ,0 ); + rc =ccw_device_start_timeout (CARD_WDEV (card), &card->write.ccw, + (addr_t ) iob,0 ,0 ,QETH_IPA_TIMEOUT );spin_unlock_irqrestore (get_ccwdev_lock (card->write.ccwdev), flags);if (rc) { QETH_DBF_MESSAGE(2, "qeth_osn_send_control_data: "
Signature · 1 line
2.13.5
PATCH 6/6 s390/qeth: use Read device to query hypervisor for MAC
In reply to Julian WiedmannFrom: Julian Wiedmann <[email protected]>
For z/VM NICs, qeth needs to consider which of the three CCW devices in an MPC group it uses for requesting a managed MAC address.
On the Base device, the hypervisor returns a default MAC which is pre-assigned when creating the NIC (this MAC is also returned by the READ MAC primitive). Querying any other device results in the allocation of an additional MAC address.
For consistency with READ MAC and to avoid using up more addresses than necessary, it is preferable to use the NIC's default MAC. So switch the the diag26c over to using a NIC's Read device, which should always be identical to the Base device.
--- drivers/s390/net/qeth_core_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/s390/net/qeth_core_main.c +1 -1
@@ -4835,7 +4835,7 @@ int qeth_vm_request_mac(struct qeth_card *card) goto out; } -ccw_device_get_id (CARD_DDEV (card), &id); +ccw_device_get_id (CARD_RDEV (card), &id); request->resp_buf_len =sizeof (*response); request->resp_version =DIAG26C_VERSION2 ; request->op_code =DIAG26C_GET_MAC ;
Signature · 1 line
2.13.5
David Miller
maintainerFrom: Julian Wiedmann <[email protected]>
Date: Thu, 19 Apr 2018 12:52:05 +0200
Quoted 6 lines
new mail address, same old me.
Please apply the following qeth fixes for 4.17. The common theme seems to be error handling improvements in various areas of cmd IO.
Patches 1-3 should also go back to stable.
Series applied and patches 1-3 queued up for -stable, thanks.