hyperv/hn: Add polling support
MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8739
This commit is contained in:
parent
b99113a1c1
commit
6c1204df36
@ -293,6 +293,7 @@ static int hn_txagg_size_sysctl(SYSCTL_HANDLER_ARGS);
|
||||
static int hn_txagg_pkts_sysctl(SYSCTL_HANDLER_ARGS);
|
||||
static int hn_txagg_pktmax_sysctl(SYSCTL_HANDLER_ARGS);
|
||||
static int hn_txagg_align_sysctl(SYSCTL_HANDLER_ARGS);
|
||||
static int hn_polling_sysctl(SYSCTL_HANDLER_ARGS);
|
||||
|
||||
static void hn_stop(struct hn_softc *);
|
||||
static void hn_init_locked(struct hn_softc *);
|
||||
@ -319,6 +320,8 @@ static void hn_resume_mgmt(struct hn_softc *);
|
||||
static void hn_suspend_mgmt_taskfunc(void *, int);
|
||||
static void hn_chan_drain(struct hn_softc *,
|
||||
struct vmbus_channel *);
|
||||
static void hn_polling(struct hn_softc *, u_int);
|
||||
static void hn_chan_polling(struct vmbus_channel *, u_int);
|
||||
|
||||
static void hn_update_link_status(struct hn_softc *);
|
||||
static void hn_change_network(struct hn_softc *);
|
||||
@ -1117,6 +1120,10 @@ hn_attach(device_t dev)
|
||||
hn_txagg_pkts_sysctl, "I",
|
||||
"Packet transmission aggregation packets, "
|
||||
"0 -- disable, -1 -- auto");
|
||||
SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "polling",
|
||||
CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0,
|
||||
hn_polling_sysctl, "I",
|
||||
"Polling frequency: [100,1000000], 0 disable polling");
|
||||
|
||||
/*
|
||||
* Setup the ifmedia, which has been initialized earlier.
|
||||
@ -2360,6 +2367,9 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Disable polling. */
|
||||
hn_polling(sc, 0);
|
||||
|
||||
/*
|
||||
* Suspend this interface before the synthetic parts
|
||||
* are ripped.
|
||||
@ -2405,6 +2415,13 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
*/
|
||||
hn_resume(sc);
|
||||
|
||||
/*
|
||||
* Re-enable polling if this interface is running and
|
||||
* the polling is requested.
|
||||
*/
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && sc->hn_pollhz > 0)
|
||||
hn_polling(sc, sc->hn_pollhz);
|
||||
|
||||
HN_UNLOCK(sc);
|
||||
break;
|
||||
|
||||
@ -2531,6 +2548,9 @@ hn_stop(struct hn_softc *sc)
|
||||
KASSERT(sc->hn_flags & HN_FLAG_SYNTH_ATTACHED,
|
||||
("synthetic parts were not attached"));
|
||||
|
||||
/* Disable polling. */
|
||||
hn_polling(sc, 0);
|
||||
|
||||
/* Clear RUNNING bit _before_ hn_suspend_data() */
|
||||
atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_RUNNING);
|
||||
hn_suspend_data(sc);
|
||||
@ -2568,6 +2588,10 @@ hn_init_locked(struct hn_softc *sc)
|
||||
|
||||
/* Everything is ready; unleash! */
|
||||
atomic_set_int(&ifp->if_drv_flags, IFF_DRV_RUNNING);
|
||||
|
||||
/* Re-enable polling if requested. */
|
||||
if (sc->hn_pollhz > 0)
|
||||
hn_polling(sc, sc->hn_pollhz);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2875,6 +2899,61 @@ hn_txagg_align_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
return (sysctl_handle_int(oidp, &align, 0, req));
|
||||
}
|
||||
|
||||
static void
|
||||
hn_chan_polling(struct vmbus_channel *chan, u_int pollhz)
|
||||
{
|
||||
if (pollhz == 0)
|
||||
vmbus_chan_poll_disable(chan);
|
||||
else
|
||||
vmbus_chan_poll_enable(chan, pollhz);
|
||||
}
|
||||
|
||||
static void
|
||||
hn_polling(struct hn_softc *sc, u_int pollhz)
|
||||
{
|
||||
int nsubch = sc->hn_rx_ring_inuse - 1;
|
||||
|
||||
HN_LOCK_ASSERT(sc);
|
||||
|
||||
if (nsubch > 0) {
|
||||
struct vmbus_channel **subch;
|
||||
int i;
|
||||
|
||||
subch = vmbus_subchan_get(sc->hn_prichan, nsubch);
|
||||
for (i = 0; i < nsubch; ++i)
|
||||
hn_chan_polling(subch[i], pollhz);
|
||||
vmbus_subchan_rel(subch, nsubch);
|
||||
}
|
||||
hn_chan_polling(sc->hn_prichan, pollhz);
|
||||
}
|
||||
|
||||
static int
|
||||
hn_polling_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct hn_softc *sc = arg1;
|
||||
int pollhz, error;
|
||||
|
||||
pollhz = sc->hn_pollhz;
|
||||
error = sysctl_handle_int(oidp, &pollhz, 0, req);
|
||||
if (error || req->newptr == NULL)
|
||||
return (error);
|
||||
|
||||
if (pollhz != 0 &&
|
||||
(pollhz < VMBUS_CHAN_POLLHZ_MIN || pollhz > VMBUS_CHAN_POLLHZ_MAX))
|
||||
return (EINVAL);
|
||||
|
||||
HN_LOCK(sc);
|
||||
if (sc->hn_pollhz != pollhz) {
|
||||
sc->hn_pollhz = pollhz;
|
||||
if ((sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING) &&
|
||||
(sc->hn_flags & HN_FLAG_SYNTH_ATTACHED))
|
||||
hn_polling(sc, sc->hn_pollhz);
|
||||
}
|
||||
HN_UNLOCK(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
|
@ -212,6 +212,8 @@ struct hn_softc {
|
||||
|
||||
uint32_t hn_caps; /* HN_CAP_ */
|
||||
uint32_t hn_flags; /* HN_FLAG_ */
|
||||
u_int hn_pollhz;
|
||||
|
||||
void *hn_rxbuf;
|
||||
uint32_t hn_rxbuf_gpadl;
|
||||
struct hyperv_dma hn_rxbuf_dma;
|
||||
|
Loading…
Reference in New Issue
Block a user