Date: Thu, 24 Nov 2016 05:18:45 +0000 (UTC) From: Sepherosa Ziehau <sephe@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r309081 - in head/sys/dev/hyperv: include vmbus Message-ID: <201611240518.uAO5IjGs048445@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: sephe Date: Thu Nov 24 05:18:45 2016 New Revision: 309081 URL: https://svnweb.freebsd.org/changeset/base/309081 Log: hyperv/vmbus: Fix the primary channel revoking on vmbus side. Drivers can now use vmbus_chan_{is_revoked,set_orphan,unset_orphan}() and vmbus_xact_ctx_orphan() to fix their attach/detach DEVMETHODs for revoked primary channels. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8545 Modified: head/sys/dev/hyperv/include/vmbus.h head/sys/dev/hyperv/vmbus/vmbus_chan.c head/sys/dev/hyperv/vmbus/vmbus_chanvar.h Modified: head/sys/dev/hyperv/include/vmbus.h ============================================================================== --- head/sys/dev/hyperv/include/vmbus.h Thu Nov 24 04:58:13 2016 (r309080) +++ head/sys/dev/hyperv/include/vmbus.h Thu Nov 24 05:18:45 2016 (r309081) @@ -116,6 +116,7 @@ struct vmbus_chan_br { }; struct vmbus_channel; +struct vmbus_xact_ctx; struct hyperv_guid; struct task; struct taskqueue; @@ -138,6 +139,9 @@ void vmbus_chan_close(struct vmbus_chan void vmbus_chan_intr_drain(struct vmbus_channel *chan); void vmbus_chan_run_task(struct vmbus_channel *chan, struct task *task); +void vmbus_chan_set_orphan(struct vmbus_channel *chan, + struct vmbus_xact_ctx *); +void vmbus_chan_unset_orphan(struct vmbus_channel *chan); int vmbus_chan_gpadl_connect(struct vmbus_channel *chan, bus_addr_t paddr, int size, uint32_t *gpadl); Modified: head/sys/dev/hyperv/vmbus/vmbus_chan.c ============================================================================== --- head/sys/dev/hyperv/vmbus/vmbus_chan.c Thu Nov 24 04:58:13 2016 (r309080) +++ head/sys/dev/hyperv/vmbus/vmbus_chan.c Thu Nov 24 05:18:45 2016 (r309081) @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include <machine/stdarg.h> #include <dev/hyperv/include/hyperv_busdma.h> +#include <dev/hyperv/include/vmbus_xact.h> #include <dev/hyperv/vmbus/hyperv_var.h> #include <dev/hyperv/vmbus/vmbus_reg.h> #include <dev/hyperv/vmbus/vmbus_var.h> @@ -1115,6 +1116,7 @@ vmbus_chan_alloc(struct vmbus_softc *sc) chan->ch_vmbus = sc; mtx_init(&chan->ch_subchan_lock, "vmbus subchan", NULL, MTX_DEF); + sx_init(&chan->ch_orphan_lock, "vmbus chorphan"); TAILQ_INIT(&chan->ch_subchans); vmbus_rxbr_init(&chan->ch_rxbr); vmbus_txbr_init(&chan->ch_txbr); @@ -1133,8 +1135,12 @@ vmbus_chan_free(struct vmbus_channel *ch VMBUS_CHAN_ST_ONPRIL | VMBUS_CHAN_ST_ONSUBL | VMBUS_CHAN_ST_ONLIST)) == 0, ("free busy channel")); + KASSERT(chan->ch_orphan_xact == NULL, + ("still has orphan xact installed")); + hyperv_dmamem_free(&chan->ch_monprm_dma, chan->ch_monprm); mtx_destroy(&chan->ch_subchan_lock); + sx_destroy(&chan->ch_orphan_lock); vmbus_rxbr_deinit(&chan->ch_rxbr); vmbus_txbr_deinit(&chan->ch_txbr); free(chan, M_DEVBUF); @@ -1403,10 +1409,21 @@ vmbus_chan_msgproc_chrescind(struct vmbu mtx_unlock(&sc->vmbus_prichan_lock); } + /* + * NOTE: + * The following processing order is critical: + * Set the REVOKED state flag before orphaning the installed xact. + */ + if (atomic_testandset_int(&chan->ch_stflags, VMBUS_CHAN_ST_REVOKED_SHIFT)) panic("channel has already been revoked"); + sx_xlock(&chan->ch_orphan_lock); + if (chan->ch_orphan_xact != NULL) + vmbus_xact_ctx_orphan(chan->ch_orphan_xact); + sx_xunlock(&chan->ch_orphan_lock); + if (bootverbose) vmbus_chan_printf(chan, "chan%u revoked\n", note->chm_chanid); @@ -1708,3 +1725,21 @@ vmbus_chan_is_revoked(const struct vmbus return (true); return (false); } + +void +vmbus_chan_set_orphan(struct vmbus_channel *chan, struct vmbus_xact_ctx *xact) +{ + + sx_xlock(&chan->ch_orphan_lock); + chan->ch_orphan_xact = xact; + sx_xunlock(&chan->ch_orphan_lock); +} + +void +vmbus_chan_unset_orphan(struct vmbus_channel *chan) +{ + + sx_xlock(&chan->ch_orphan_lock); + chan->ch_orphan_xact = NULL; + sx_xunlock(&chan->ch_orphan_lock); +} Modified: head/sys/dev/hyperv/vmbus/vmbus_chanvar.h ============================================================================== --- head/sys/dev/hyperv/vmbus/vmbus_chanvar.h Thu Nov 24 04:58:13 2016 (r309080) +++ head/sys/dev/hyperv/vmbus/vmbus_chanvar.h Thu Nov 24 05:18:45 2016 (r309081) @@ -33,8 +33,9 @@ #include <sys/lock.h> #include <sys/mutex.h> #include <sys/queue.h> -#include <sys/taskqueue.h> #include <sys/sysctl.h> +#include <sys/sx.h> +#include <sys/taskqueue.h> #include <dev/hyperv/include/hyperv.h> #include <dev/hyperv/include/hyperv_busdma.h> @@ -138,6 +139,9 @@ struct vmbus_channel { struct hyperv_guid ch_guid_type; struct hyperv_guid ch_guid_inst; + struct sx ch_orphan_lock; + struct vmbus_xact_ctx *ch_orphan_xact; + struct sysctl_ctx_list ch_sysctl_ctx; } __aligned(CACHE_LINE_SIZE);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611240518.uAO5IjGs048445>