From 566caca07e832a12df283298eb92624457917107 Mon Sep 17 00:00:00 2001 From: stsp Date: Sat, 27 Jan 2018 13:44:03 +0000 Subject: [PATCH] Fix an interrupt storm issue in vnet(4) mpi@ managed to trigger on my T5220, similar to the issue fixed in vldcp(4) recently. For good measure also fix it again in vldcp(4) in case the Rx channel is reset rather than goes down. My T5220 has been running fine with this change. ok kettenis@ --- sys/arch/sparc64/dev/vldcp.c | 16 ++++++++++++---- sys/arch/sparc64/dev/vnet.c | 18 +++++++++++++++++- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/sys/arch/sparc64/dev/vldcp.c b/sys/arch/sparc64/dev/vldcp.c index 5aed7b206fe..470d1dcf908 100644 --- a/sys/arch/sparc64/dev/vldcp.c +++ b/sys/arch/sparc64/dev/vldcp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vldcp.c,v 1.15 2018/01/17 15:52:34 stsp Exp $ */ +/* $OpenBSD: vldcp.c,v 1.16 2018/01/27 13:44:03 stsp Exp $ */ /* * Copyright (c) 2009, 2012 Mark Kettenis * @@ -251,7 +251,7 @@ vldcp_rx_intr(void *arg) if (rx_head == rx_tail) break; /* Discard and ack pending I/O. */ - DPRINTF(("setting rx qhead to %lld\n", rx_tail)); + DPRINTF(("setting rx qhead to %llx\n", rx_tail)); err = hv_ldc_rx_set_qhead(lc->lc_id, rx_tail); if (err == H_EOK) break; @@ -262,6 +262,14 @@ vldcp_rx_intr(void *arg) break; case LDC_CHANNEL_RESET: DPRINTF(("%s: Rx link reset\n", __func__)); + if (rx_head == rx_tail) + break; + /* Discard and ack pending I/O. */ + DPRINTF(("setting rx qhead to %llx\n", rx_tail)); + err = hv_ldc_rx_set_qhead(lc->lc_id, rx_tail); + if (err == H_EOK) + break; + printf("%s: hv_ldc_rx_set_qhead %d\n", __func__, err); break; } lc->lc_rx_state = rx_state; @@ -378,14 +386,14 @@ retry: return (EIO); } + DPRINTF(("rx head %llx, rx tail %llx, state %lld\n", rx_head, rx_tail, rx_state)); + if (rx_state != LDC_CHANNEL_UP) { splx(s); device_unref(&sc->sc_dv); return (EIO); } - DPRINTF(("rx head %llx, rx tail %llx\n", rx_head, rx_tail)); - if (rx_head == rx_tail) { cbus_intr_setenabled(sc->sc_bustag, sc->sc_rx_ino, INTR_ENABLED); diff --git a/sys/arch/sparc64/dev/vnet.c b/sys/arch/sparc64/dev/vnet.c index 4d1e96bbadb..147caf1f2ec 100644 --- a/sys/arch/sparc64/dev/vnet.c +++ b/sys/arch/sparc64/dev/vnet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vnet.c,v 1.59 2018/01/17 15:52:34 stsp Exp $ */ +/* $OpenBSD: vnet.c,v 1.60 2018/01/27 13:44:03 stsp Exp $ */ /* * Copyright (c) 2009, 2015 Mark Kettenis * @@ -380,6 +380,14 @@ vnet_rx_intr(void *arg) lc->lc_tx_seqid = 0; lc->lc_state = 0; lc->lc_reset(lc); + if (rx_head == rx_tail) + break; + /* Discard and ack pending I/O. */ + DPRINTF(("setting rx qhead to %lld\n", rx_tail)); + err = hv_ldc_rx_set_qhead(lc->lc_id, rx_tail); + if (err == H_EOK) + break; + printf("%s: hv_ldc_rx_set_qhead %d\n", __func__, err); break; case LDC_CHANNEL_UP: DPRINTF(("%s: Rx link up\n", __func__)); @@ -391,6 +399,14 @@ vnet_rx_intr(void *arg) lc->lc_state = 0; lc->lc_reset(lc); timeout_add_msec(&sc->sc_handshake_to, 500); + if (rx_head == rx_tail) + break; + /* Discard and ack pending I/O. */ + DPRINTF(("setting rx qhead to %lld\n", rx_tail)); + err = hv_ldc_rx_set_qhead(lc->lc_id, rx_tail); + if (err == H_EOK) + break; + printf("%s: hv_ldc_rx_set_qhead %d\n", __func__, err); break; } lc->lc_rx_state = rx_state; -- 2.20.1