aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/netmap/if_ptnet.c
diff options
context:
space:
mode:
authorVincenzo Maffione <vmaffione@FreeBSD.org>2018-12-11 11:31:13 +0000
committerVincenzo Maffione <vmaffione@FreeBSD.org>2018-12-11 11:31:13 +0000
commitb321acab165f6ab6e821be03895eb40e5bff6fe7 (patch)
tree4d73b629a9f886d9a16a3f196593c929c4247c26 /sys/dev/netmap/if_ptnet.c
parent57b85cb534b8a7aa8900ef7f3b45cd0846a31f76 (diff)
Notes
Diffstat (limited to 'sys/dev/netmap/if_ptnet.c')
-rw-r--r--sys/dev/netmap/if_ptnet.c166
1 files changed, 75 insertions, 91 deletions
diff --git a/sys/dev/netmap/if_ptnet.c b/sys/dev/netmap/if_ptnet.c
index 55137f2706da..c362018b95af 100644
--- a/sys/dev/netmap/if_ptnet.c
+++ b/sys/dev/netmap/if_ptnet.c
@@ -128,8 +128,8 @@ struct ptnet_queue {
struct resource *irq;
void *cookie;
int kring_id;
- struct ptnet_csb_gh *ptgh;
- struct ptnet_csb_hg *pthg;
+ struct nm_csb_atok *atok;
+ struct nm_csb_ktoa *ktoa;
unsigned int kick;
struct mtx lock;
struct buf_ring *bufring; /* for TX queues */
@@ -166,8 +166,8 @@ struct ptnet_softc {
unsigned int num_tx_rings;
struct ptnet_queue *queues;
struct ptnet_queue *rxqueues;
- struct ptnet_csb_gh *csb_gh;
- struct ptnet_csb_hg *csb_hg;
+ struct nm_csb_atok *csb_gh;
+ struct nm_csb_ktoa *csb_hg;
unsigned int min_tx_space;
@@ -209,7 +209,7 @@ static void ptnet_tick(void *opaque);
static int ptnet_irqs_init(struct ptnet_softc *sc);
static void ptnet_irqs_fini(struct ptnet_softc *sc);
-static uint32_t ptnet_nm_ptctl(if_t ifp, uint32_t cmd);
+static uint32_t ptnet_nm_ptctl(struct ptnet_softc *sc, uint32_t cmd);
static int ptnet_nm_config(struct netmap_adapter *na,
struct nm_config_info *info);
static void ptnet_update_vnet_hdr(struct ptnet_softc *sc);
@@ -327,7 +327,7 @@ ptnet_attach(device_t dev)
sc->num_rings = num_tx_rings + num_rx_rings;
sc->num_tx_rings = num_tx_rings;
- if (sc->num_rings * sizeof(struct ptnet_csb_gh) > PAGE_SIZE) {
+ if (sc->num_rings * sizeof(struct nm_csb_atok) > PAGE_SIZE) {
device_printf(dev, "CSB cannot handle that many rings (%u)\n",
sc->num_rings);
err = ENOMEM;
@@ -342,7 +342,7 @@ ptnet_attach(device_t dev)
err = ENOMEM;
goto err_path;
}
- sc->csb_hg = (struct ptnet_csb_hg *)(((char *)sc->csb_gh) + PAGE_SIZE);
+ sc->csb_hg = (struct nm_csb_ktoa *)(((char *)sc->csb_gh) + PAGE_SIZE);
{
/*
@@ -379,8 +379,8 @@ ptnet_attach(device_t dev)
pq->sc = sc;
pq->kring_id = i;
pq->kick = PTNET_IO_KICK_BASE + 4 * i;
- pq->ptgh = sc->csb_gh + i;
- pq->pthg = sc->csb_hg + i;
+ pq->atok = sc->csb_gh + i;
+ pq->ktoa = sc->csb_hg + i;
snprintf(pq->lock_name, sizeof(pq->lock_name), "%s-%d",
device_get_nameunit(dev), i);
mtx_init(&pq->lock, pq->lock_name, NULL, MTX_DEF);
@@ -505,12 +505,25 @@ err_path:
return err;
}
+/* Stop host sync-kloop if it was running. */
+static void
+ptnet_device_shutdown(struct ptnet_softc *sc)
+{
+ ptnet_nm_ptctl(sc, PTNETMAP_PTCTL_DELETE);
+ bus_write_4(sc->iomem, PTNET_IO_CSB_GH_BAH, 0);
+ bus_write_4(sc->iomem, PTNET_IO_CSB_GH_BAL, 0);
+ bus_write_4(sc->iomem, PTNET_IO_CSB_HG_BAH, 0);
+ bus_write_4(sc->iomem, PTNET_IO_CSB_HG_BAL, 0);
+}
+
static int
ptnet_detach(device_t dev)
{
struct ptnet_softc *sc = device_get_softc(dev);
int i;
+ ptnet_device_shutdown(sc);
+
#ifdef DEVICE_POLLING
if (sc->ifp->if_capenable & IFCAP_POLLING) {
ether_poll_deregister(sc->ifp);
@@ -543,10 +556,6 @@ ptnet_detach(device_t dev)
ptnet_irqs_fini(sc);
if (sc->csb_gh) {
- bus_write_4(sc->iomem, PTNET_IO_CSB_GH_BAH, 0);
- bus_write_4(sc->iomem, PTNET_IO_CSB_GH_BAL, 0);
- bus_write_4(sc->iomem, PTNET_IO_CSB_HG_BAH, 0);
- bus_write_4(sc->iomem, PTNET_IO_CSB_HG_BAL, 0);
contigfree(sc->csb_gh, 2*PAGE_SIZE, M_DEVBUF);
sc->csb_gh = NULL;
sc->csb_hg = NULL;
@@ -583,9 +592,8 @@ ptnet_detach(device_t dev)
static int
ptnet_suspend(device_t dev)
{
- struct ptnet_softc *sc;
+ struct ptnet_softc *sc = device_get_softc(dev);
- sc = device_get_softc(dev);
(void)sc;
return (0);
@@ -594,9 +602,8 @@ ptnet_suspend(device_t dev)
static int
ptnet_resume(device_t dev)
{
- struct ptnet_softc *sc;
+ struct ptnet_softc *sc = device_get_softc(dev);
- sc = device_get_softc(dev);
(void)sc;
return (0);
@@ -605,11 +612,11 @@ ptnet_resume(device_t dev)
static int
ptnet_shutdown(device_t dev)
{
- /*
- * Suspend already does all of what we need to
- * do here; we just never expect to be resumed.
- */
- return (ptnet_suspend(dev));
+ struct ptnet_softc *sc = device_get_softc(dev);
+
+ ptnet_device_shutdown(sc);
+
+ return (0);
}
static int
@@ -796,7 +803,7 @@ ptnet_ioctl(if_t ifp, u_long cmd, caddr_t data)
/* Make sure the worker sees the
* IFF_DRV_RUNNING down. */
PTNET_Q_LOCK(pq);
- pq->ptgh->guest_need_kick = 0;
+ pq->atok->appl_need_kick = 0;
PTNET_Q_UNLOCK(pq);
/* Wait for rescheduling to finish. */
if (pq->taskq) {
@@ -810,7 +817,7 @@ ptnet_ioctl(if_t ifp, u_long cmd, caddr_t data)
for (i = 0; i < sc->num_rings; i++) {
pq = sc-> queues + i;
PTNET_Q_LOCK(pq);
- pq->ptgh->guest_need_kick = 1;
+ pq->atok->appl_need_kick = 1;
PTNET_Q_UNLOCK(pq);
}
}
@@ -881,7 +888,7 @@ ptnet_init_locked(struct ptnet_softc *sc)
return ret;
}
- if (sc->ptna->backend_regifs == 0) {
+ if (sc->ptna->backend_users == 0) {
ret = ptnet_nm_krings_create(na_nm);
if (ret) {
device_printf(sc->dev, "ptnet_nm_krings_create() "
@@ -962,7 +969,7 @@ ptnet_stop(struct ptnet_softc *sc)
ptnet_nm_register(na_dr, 0 /* off */);
- if (sc->ptna->backend_regifs == 0) {
+ if (sc->ptna->backend_users == 0) {
netmap_mem_rings_delete(na_dr);
ptnet_nm_krings_delete(na_nm);
}
@@ -1092,9 +1099,8 @@ ptnet_media_status(if_t ifp, struct ifmediareq *ifmr)
}
static uint32_t
-ptnet_nm_ptctl(if_t ifp, uint32_t cmd)
+ptnet_nm_ptctl(struct ptnet_softc *sc, uint32_t cmd)
{
- struct ptnet_softc *sc = if_getsoftc(ifp);
/*
* Write a command and read back error status,
* with zero meaning success.
@@ -1130,8 +1136,8 @@ ptnet_sync_from_csb(struct ptnet_softc *sc, struct netmap_adapter *na)
/* Sync krings from the host, reading from
* CSB. */
for (i = 0; i < sc->num_rings; i++) {
- struct ptnet_csb_gh *ptgh = sc->queues[i].ptgh;
- struct ptnet_csb_hg *pthg = sc->queues[i].pthg;
+ struct nm_csb_atok *atok = sc->queues[i].atok;
+ struct nm_csb_ktoa *ktoa = sc->queues[i].ktoa;
struct netmap_kring *kring;
if (i < na->num_tx_rings) {
@@ -1139,15 +1145,15 @@ ptnet_sync_from_csb(struct ptnet_softc *sc, struct netmap_adapter *na)
} else {
kring = na->rx_rings[i - na->num_tx_rings];
}
- kring->rhead = kring->ring->head = ptgh->head;
- kring->rcur = kring->ring->cur = ptgh->cur;
- kring->nr_hwcur = pthg->hwcur;
+ kring->rhead = kring->ring->head = atok->head;
+ kring->rcur = kring->ring->cur = atok->cur;
+ kring->nr_hwcur = ktoa->hwcur;
kring->nr_hwtail = kring->rtail =
- kring->ring->tail = pthg->hwtail;
+ kring->ring->tail = ktoa->hwtail;
ND("%d,%d: csb {hc %u h %u c %u ht %u}", t, i,
- pthg->hwcur, ptgh->head, ptgh->cur,
- pthg->hwtail);
+ ktoa->hwcur, atok->head, atok->cur,
+ ktoa->hwtail);
ND("%d,%d: kring {hc %u rh %u rc %u h %u c %u ht %u rt %u t %u}",
t, i, kring->nr_hwcur, kring->rhead, kring->rcur,
kring->ring->head, kring->ring->cur, kring->nr_hwtail,
@@ -1178,7 +1184,7 @@ ptnet_nm_register(struct netmap_adapter *na, int onoff)
int i;
if (!onoff) {
- sc->ptna->backend_regifs--;
+ sc->ptna->backend_users--;
}
/* If this is the last netmap client, guest interrupt enable flags may
@@ -1191,17 +1197,17 @@ ptnet_nm_register(struct netmap_adapter *na, int onoff)
D("Exit netmap mode, re-enable interrupts");
for (i = 0; i < sc->num_rings; i++) {
pq = sc->queues + i;
- pq->ptgh->guest_need_kick = 1;
+ pq->atok->appl_need_kick = 1;
}
}
if (onoff) {
- if (sc->ptna->backend_regifs == 0) {
+ if (sc->ptna->backend_users == 0) {
/* Initialize notification enable fields in the CSB. */
for (i = 0; i < sc->num_rings; i++) {
pq = sc->queues + i;
- pq->pthg->host_need_kick = 1;
- pq->ptgh->guest_need_kick =
+ pq->ktoa->kern_need_kick = 1;
+ pq->atok->appl_need_kick =
(!(ifp->if_capenable & IFCAP_POLLING)
&& i >= sc->num_tx_rings);
}
@@ -1211,17 +1217,13 @@ ptnet_nm_register(struct netmap_adapter *na, int onoff)
/* Make sure the host adapter passed through is ready
* for txsync/rxsync. */
- ret = ptnet_nm_ptctl(ifp, PTNETMAP_PTCTL_CREATE);
+ ret = ptnet_nm_ptctl(sc, PTNETMAP_PTCTL_CREATE);
if (ret) {
return ret;
}
- }
- /* Sync from CSB must be done after REGIF PTCTL. Skip this
- * step only if this is a netmap client and it is not the
- * first one. */
- if ((!native && sc->ptna->backend_regifs == 0) ||
- (native && na->active_fds == 0)) {
+ /* Align the guest krings and rings to the state stored
+ * in the CSB. */
ptnet_sync_from_csb(sc, na);
}
@@ -1254,19 +1256,13 @@ ptnet_nm_register(struct netmap_adapter *na, int onoff)
}
}
- /* Sync from CSB must be done before UNREGIF PTCTL, on the last
- * netmap client. */
- if (native && na->active_fds == 0) {
- ptnet_sync_from_csb(sc, na);
- }
-
- if (sc->ptna->backend_regifs == 0) {
- ret = ptnet_nm_ptctl(ifp, PTNETMAP_PTCTL_DELETE);
+ if (sc->ptna->backend_users == 0) {
+ ret = ptnet_nm_ptctl(sc, PTNETMAP_PTCTL_DELETE);
}
}
if (onoff) {
- sc->ptna->backend_regifs++;
+ sc->ptna->backend_users++;
}
return ret;
@@ -1279,7 +1275,7 @@ ptnet_nm_txsync(struct netmap_kring *kring, int flags)
struct ptnet_queue *pq = sc->queues + kring->ring_id;
bool notify;
- notify = netmap_pt_guest_txsync(pq->ptgh, pq->pthg, kring, flags);
+ notify = netmap_pt_guest_txsync(pq->atok, pq->ktoa, kring, flags);
if (notify) {
ptnet_kick(pq);
}
@@ -1294,7 +1290,7 @@ ptnet_nm_rxsync(struct netmap_kring *kring, int flags)
struct ptnet_queue *pq = sc->rxqueues + kring->ring_id;
bool notify;
- notify = netmap_pt_guest_rxsync(pq->ptgh, pq->pthg, kring, flags);
+ notify = netmap_pt_guest_rxsync(pq->atok, pq->ktoa, kring, flags);
if (notify) {
ptnet_kick(pq);
}
@@ -1310,7 +1306,7 @@ ptnet_nm_intr(struct netmap_adapter *na, int onoff)
for (i = 0; i < sc->num_rings; i++) {
struct ptnet_queue *pq = sc->queues + i;
- pq->ptgh->guest_need_kick = onoff;
+ pq->atok->appl_need_kick = onoff;
}
}
@@ -1676,25 +1672,13 @@ ptnet_rx_csum(struct mbuf *m, struct virtio_net_hdr *hdr)
}
/* End of offloading-related functions to be shared with vtnet. */
-static inline void
-ptnet_sync_tail(struct ptnet_csb_hg *pthg, struct netmap_kring *kring)
-{
- struct netmap_ring *ring = kring->ring;
-
- /* Update hwcur and hwtail as known by the host. */
- ptnetmap_guest_read_kring_csb(pthg, kring);
-
- /* nm_sync_finalize */
- ring->tail = kring->rtail = kring->nr_hwtail;
-}
-
static void
ptnet_ring_update(struct ptnet_queue *pq, struct netmap_kring *kring,
unsigned int head, unsigned int sync_flags)
{
struct netmap_ring *ring = kring->ring;
- struct ptnet_csb_gh *ptgh = pq->ptgh;
- struct ptnet_csb_hg *pthg = pq->pthg;
+ struct nm_csb_atok *atok = pq->atok;
+ struct nm_csb_ktoa *ktoa = pq->ktoa;
/* Some packets have been pushed to the netmap ring. We have
* to tell the host to process the new packets, updating cur
@@ -1704,11 +1688,11 @@ ptnet_ring_update(struct ptnet_queue *pq, struct netmap_kring *kring,
/* Mimic nm_txsync_prologue/nm_rxsync_prologue. */
kring->rcur = kring->rhead = head;
- ptnetmap_guest_write_kring_csb(ptgh, kring->rcur, kring->rhead);
+ ptnetmap_guest_write_kring_csb(atok, kring->rcur, kring->rhead);
/* Kick the host if needed. */
- if (NM_ACCESS_ONCE(pthg->host_need_kick)) {
- ptgh->sync_flags = sync_flags;
+ if (NM_ACCESS_ONCE(ktoa->kern_need_kick)) {
+ atok->sync_flags = sync_flags;
ptnet_kick(pq);
}
}
@@ -1728,8 +1712,8 @@ ptnet_drain_transmit_queue(struct ptnet_queue *pq, unsigned int budget,
struct netmap_adapter *na = &sc->ptna->dr.up;
if_t ifp = sc->ifp;
unsigned int batch_count = 0;
- struct ptnet_csb_gh *ptgh;
- struct ptnet_csb_hg *pthg;
+ struct nm_csb_atok *atok;
+ struct nm_csb_ktoa *ktoa;
struct netmap_kring *kring;
struct netmap_ring *ring;
struct netmap_slot *slot;
@@ -1758,8 +1742,8 @@ ptnet_drain_transmit_queue(struct ptnet_queue *pq, unsigned int budget,
return ENETDOWN;
}
- ptgh = pq->ptgh;
- pthg = pq->pthg;
+ atok = pq->atok;
+ ktoa = pq->ktoa;
kring = na->tx_rings[pq->kring_id];
ring = kring->ring;
lim = kring->nkr_num_slots - 1;
@@ -1771,17 +1755,17 @@ ptnet_drain_transmit_queue(struct ptnet_queue *pq, unsigned int budget,
/* We ran out of slot, let's see if the host has
* freed up some, by reading hwcur and hwtail from
* the CSB. */
- ptnet_sync_tail(pthg, kring);
+ ptnet_sync_tail(ktoa, kring);
if (PTNET_TX_NOSPACE(head, kring, minspace)) {
/* Still no slots available. Reactivate the
* interrupts so that we can be notified
* when some free slots are made available by
* the host. */
- ptgh->guest_need_kick = 1;
+ atok->appl_need_kick = 1;
/* Double-check. */
- ptnet_sync_tail(pthg, kring);
+ ptnet_sync_tail(ktoa, kring);
if (likely(PTNET_TX_NOSPACE(head, kring,
minspace))) {
break;
@@ -1790,7 +1774,7 @@ ptnet_drain_transmit_queue(struct ptnet_queue *pq, unsigned int budget,
RD(1, "Found more slots by doublecheck");
/* More slots were freed before reactivating
* the interrupts. */
- ptgh->guest_need_kick = 0;
+ atok->appl_need_kick = 0;
}
}
@@ -2020,8 +2004,8 @@ ptnet_rx_eof(struct ptnet_queue *pq, unsigned int budget, bool may_resched)
{
struct ptnet_softc *sc = pq->sc;
bool have_vnet_hdr = sc->vnet_hdr_len;
- struct ptnet_csb_gh *ptgh = pq->ptgh;
- struct ptnet_csb_hg *pthg = pq->pthg;
+ struct nm_csb_atok *atok = pq->atok;
+ struct nm_csb_ktoa *ktoa = pq->ktoa;
struct netmap_adapter *na = &sc->ptna->dr.up;
struct netmap_kring *kring = na->rx_rings[pq->kring_id];
struct netmap_ring *ring = kring->ring;
@@ -2053,21 +2037,21 @@ host_sync:
/* We ran out of slot, let's see if the host has
* added some, by reading hwcur and hwtail from
* the CSB. */
- ptnet_sync_tail(pthg, kring);
+ ptnet_sync_tail(ktoa, kring);
if (head == ring->tail) {
/* Still no slots available. Reactivate
* interrupts as they were disabled by the
* host thread right before issuing the
* last interrupt. */
- ptgh->guest_need_kick = 1;
+ atok->appl_need_kick = 1;
/* Double-check. */
- ptnet_sync_tail(pthg, kring);
+ ptnet_sync_tail(ktoa, kring);
if (likely(head == ring->tail)) {
break;
}
- ptgh->guest_need_kick = 0;
+ atok->appl_need_kick = 0;
}
}