1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-18 15:30:21 +00:00

Add netdump support to vtnet(4).

Tested with bhyve.

Reviewed by:	bryanv, julian
MFC after:	1 month
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D15261
This commit is contained in:
Mark Johnston 2018-05-06 00:53:52 +00:00
parent 306c97e2d8
commit c857c7d553
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=333290

View File

@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/sctp.h>
#include <netinet/netdump/netdump.h>
#include <machine/bus.h>
#include <machine/resource.h>
@ -143,7 +144,7 @@ static struct mbuf *
struct virtio_net_hdr *);
static int vtnet_txq_enqueue_buf(struct vtnet_txq *, struct mbuf **,
struct vtnet_tx_header *);
static int vtnet_txq_encap(struct vtnet_txq *, struct mbuf **);
static int vtnet_txq_encap(struct vtnet_txq *, struct mbuf **, int);
#ifdef VTNET_LEGACY_TX
static void vtnet_start_locked(struct vtnet_txq *, struct ifnet *);
static void vtnet_start(struct ifnet *);
@ -231,6 +232,8 @@ static void vtnet_disable_interrupts(struct vtnet_softc *);
static int vtnet_tunable_int(struct vtnet_softc *, const char *, int);
NETDUMP_DEFINE(vtnet);
/* Tunables. */
static SYSCTL_NODE(_hw, OID_AUTO, vtnet, CTLFLAG_RD, 0, "VNET driver parameters");
static int vtnet_csum_disable = 0;
@ -1026,6 +1029,8 @@ vtnet_setup_interface(struct vtnet_softc *sc)
vtnet_set_rx_process_limit(sc);
vtnet_set_tx_intr_threshold(sc);
NETDUMP_SET(ifp, vtnet);
return (0);
}
@ -2176,7 +2181,7 @@ vtnet_txq_enqueue_buf(struct vtnet_txq *txq, struct mbuf **m_head,
}
static int
vtnet_txq_encap(struct vtnet_txq *txq, struct mbuf **m_head)
vtnet_txq_encap(struct vtnet_txq *txq, struct mbuf **m_head, int flags)
{
struct vtnet_tx_header *txhdr;
struct virtio_net_hdr *hdr;
@ -2186,7 +2191,7 @@ vtnet_txq_encap(struct vtnet_txq *txq, struct mbuf **m_head)
m = *m_head;
M_ASSERTPKTHDR(m);
txhdr = uma_zalloc(vtnet_tx_header_zone, M_NOWAIT | M_ZERO);
txhdr = uma_zalloc(vtnet_tx_header_zone, flags | M_ZERO);
if (txhdr == NULL) {
m_freem(m);
*m_head = NULL;
@ -2260,7 +2265,7 @@ vtnet_start_locked(struct vtnet_txq *txq, struct ifnet *ifp)
if (m0 == NULL)
break;
if (vtnet_txq_encap(txq, &m0) != 0) {
if (vtnet_txq_encap(txq, &m0, M_NOWAIT) != 0) {
if (m0 != NULL)
IFQ_DRV_PREPEND(&ifp->if_snd, m0);
break;
@ -2337,7 +2342,7 @@ vtnet_txq_mq_start_locked(struct vtnet_txq *txq, struct mbuf *m)
break;
}
if (vtnet_txq_encap(txq, &m) != 0) {
if (vtnet_txq_encap(txq, &m, M_NOWAIT) != 0) {
if (m != NULL)
drbr_putback(ifp, br, m);
else
@ -3976,3 +3981,69 @@ vtnet_tunable_int(struct vtnet_softc *sc, const char *knob, int def)
return (def);
}
#ifdef NETDUMP
static void
vtnet_netdump_init(struct ifnet *ifp, int *nrxr, int *ncl, int *clsize)
{
struct vtnet_softc *sc;
sc = if_getsoftc(ifp);
VTNET_CORE_LOCK(sc);
*nrxr = sc->vtnet_max_vq_pairs;
*ncl = NETDUMP_MAX_IN_FLIGHT;
*clsize = sc->vtnet_rx_clsize;
VTNET_CORE_UNLOCK(sc);
/*
* We need to allocate from this zone in the transmit path, so ensure
* that we have at least one item per header available.
* XXX add a separate zone like we do for mbufs? otherwise we may alloc
* buckets
*/
uma_zone_reserve(vtnet_tx_header_zone, NETDUMP_MAX_IN_FLIGHT * 2);
uma_prealloc(vtnet_tx_header_zone, NETDUMP_MAX_IN_FLIGHT * 2);
}
static void
vtnet_netdump_event(struct ifnet *ifp __unused, enum netdump_ev event __unused)
{
}
static int
vtnet_netdump_transmit(struct ifnet *ifp, struct mbuf *m)
{
struct vtnet_softc *sc;
struct vtnet_txq *txq;
int error;
sc = if_getsoftc(ifp);
if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
IFF_DRV_RUNNING)
return (EBUSY);
txq = &sc->vtnet_txqs[0];
error = vtnet_txq_encap(txq, &m, M_NOWAIT | M_USE_RESERVE);
if (error == 0)
(void)vtnet_txq_notify(txq);
return (error);
}
static int
vtnet_netdump_poll(struct ifnet *ifp, int count)
{
struct vtnet_softc *sc;
int i;
sc = if_getsoftc(ifp);
if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
IFF_DRV_RUNNING)
return (EBUSY);
(void)vtnet_txq_eof(&sc->vtnet_txqs[0]);
for (i = 0; i < sc->vtnet_max_vq_pairs; i++)
(void)vtnet_rxq_eof(&sc->vtnet_rxqs[i]);
return (0);
}
#endif /* NETDUMP */