Date: Fri, 5 Aug 2016 13:54:56 GMT From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307219 - soc2016/vincenzo/head/usr.sbin/bhyve Message-ID: <201608051354.u75Dsuw1037808@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: vincenzo Date: Fri Aug 5 13:54:55 2016 New Revision: 307219 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307219 Log: ptnetmap: add backend-side support Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 13:53:35 2016 (r307218) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 13:54:55 2016 (r307219) @@ -55,6 +55,7 @@ #if (NETMAP_API < 11) #error "Netmap API version must be >= 11" #endif +#include <dev/netmap/netmap_virt.h> /* * The API for network backends. This might need to be exposed @@ -109,11 +110,6 @@ int (*set_features)(struct net_backend *be, uint64_t features, unsigned int vnet_hdr_len); - /* - * Get ptnetmap_state if the backend support ptnetmap - */ - struct ptnetmap_state * (*get_ptnetmap)(struct net_backend *be); - struct pci_vtnet_softc *sc; int fd; unsigned int be_vnet_hdr_len; @@ -171,12 +167,6 @@ return -1; /* never called, i believe */ } -static struct ptnetmap_state * -netbe_null_get_ptnetmap(struct net_backend *be) -{ - return NULL; -} - static struct net_backend null_backend = { .name = "null", .init = netbe_null_init, @@ -185,7 +175,6 @@ .recv = netbe_null_recv, .get_features = netbe_null_get_features, .set_features = netbe_null_set_features, - .get_ptnetmap = netbe_null_get_ptnetmap, }; DATA_SET(net_backend_set, null_backend); @@ -341,6 +330,8 @@ #define NETMAP_POLLMASK (POLLIN | POLLRDNORM | POLLRDBAND) +#define VNET_HDR_LEN sizeof(struct virtio_net_rxhdr) + struct netmap_priv { char ifname[IFNAMSIZ]; struct nm_desc *nmd; @@ -357,6 +348,8 @@ int rx_avail; int rx_morefrag; int rx_avail_slots; + + struct ptnetmap_state ptnetmap; }; static void * @@ -405,10 +398,31 @@ return 0; } +static int +netmap_has_vnet_hdr_len(struct net_backend *be, unsigned vnet_hdr_len) +{ + int prev_hdr_len = be->be_vnet_hdr_len; + int ret; + + if (vnet_hdr_len == prev_hdr_len) { + return 1; + } + + ret = netmap_set_vnet_hdr_len(be, vnet_hdr_len); + if (ret) { + return 0; + } + + netmap_set_vnet_hdr_len(be, prev_hdr_len); + + return 1; +} + static uint64_t netmap_get_features(struct net_backend *be) { - return NETMAP_FEATURES; + return netmap_has_vnet_hdr_len(be, VNET_HDR_LEN) ? + NETMAP_FEATURES : 0; } static int @@ -418,7 +432,125 @@ return netmap_set_vnet_hdr_len(be, vnet_hdr_len); } -/* used by netmap and ptnetmap during the initialization */ +/* Store and return the features we agreed upon. */ +uint32_t +ptnetmap_ack_features(struct ptnetmap_state *ptn, uint32_t wanted_features) +{ + ptn->acked_features = ptn->features & wanted_features; + + return ptn->acked_features; +} + +struct ptnetmap_state * +get_ptnetmap(struct net_backend *be) +{ + struct netmap_priv *priv = be->priv; + + /* Check that this is a netmap backend. */ + if (be->set_features != netmap_set_features) { + return NULL; + } + + return &priv->ptnetmap; +} + +int +ptnetmap_get_netmap_if(struct ptnetmap_state *ptn, struct netmap_if_info *nif) +{ + struct netmap_priv *priv = ptn->netmap_priv; + + memset(nif, 0, sizeof(*nif)); + if (priv->nmd == NULL) { + return EINVAL; + } + + nif->nifp_offset = priv->nmd->req.nr_offset; + nif->num_tx_rings = priv->nmd->req.nr_tx_rings; + nif->num_rx_rings = priv->nmd->req.nr_rx_rings; + nif->num_tx_slots = priv->nmd->req.nr_tx_slots; + nif->num_rx_slots = priv->nmd->req.nr_rx_slots; + + return 0; +} + +int +ptnetmap_get_host_memid(struct ptnetmap_state *ptn) +{ + struct netmap_priv *priv = ptn->netmap_priv; + + if (priv->nmd == NULL) { + return EINVAL; + } + + return priv->nmd->req.nr_arg2; +} + +int +ptnetmap_create(struct ptnetmap_state *ptn, struct ptnetmap_cfg *cfg) +{ + struct netmap_priv *priv = ptn->netmap_priv; + struct nmreq req; + int err; + + if (!(ptn->acked_features & NET_PTN_FEATURES_BASE)) { + fprintf(stderr, "%s: ptnetmap features not acked\n", + __func__); + return EINVAL; + } + + if (ptn->running) { + return 0; + } + + /* XXX We should stop the netmap evloop here. */ + + /* Ask netmap to create kthreads for this interface. */ + memset(&req, 0, sizeof(req)); + strncpy(req.nr_name, priv->ifname, sizeof(req.nr_name)); + req.nr_version = NETMAP_API; + ptnetmap_write_cfg(&req, cfg); + req.nr_cmd = NETMAP_PT_HOST_CREATE; + err = ioctl(priv->nmd->fd, NIOCREGIF, &req); + if (err) { + fprintf(stderr, "%s: Unable to create ptnetmap kthreads on " + "%s [errno=%d]", __func__, priv->ifname, errno); + return err; + } + + ptn->running = 1; + + return 0; +} + +int +ptnetmap_delete(struct ptnetmap_state *ptn) +{ + struct netmap_priv *priv = ptn->netmap_priv; + struct nmreq req; + int err; + + if (!ptn->running) { + return 0; + } + + /* Ask netmap to delete kthreads for this interface. */ + memset(&req, 0, sizeof(req)); + strncpy(req.nr_name, priv->ifname, sizeof(req.nr_name)); + req.nr_version = NETMAP_API; + req.nr_cmd = NETMAP_PT_HOST_DELETE; + err = ioctl(priv->nmd->fd, NIOCREGIF, &req); + if (err) { + fprintf(stderr, "%s: Unable to create ptnetmap kthreads on " + "%s [errno=%d]", __func__, priv->ifname, errno); + return err; + } + + ptn->running = 0; + + return 0; +} + +/* Used by netmap at initialization time. */ static int netmap_common_init(struct net_backend *be, struct netmap_priv *priv, uint32_t nr_flags, const char *devname, @@ -467,6 +599,7 @@ net_backend_cb_t cb, void *param) { struct netmap_priv *priv = NULL; + int ptnetmap = 0; priv = calloc(1, sizeof(struct netmap_priv)); if (priv == NULL) { @@ -474,10 +607,24 @@ return -1; } - if (netmap_common_init(be, priv, 0, devname, cb, param)) { + if (netmap_common_init(be, priv, ptnetmap ? NR_PTNETMAP_HOST : 0, + devname, cb, param)) { goto err; } + if (ptnetmap) { + priv->ptnetmap.netmap_priv = priv; + priv->ptnetmap.features = NET_PTN_FEATURES_BASE; + priv->ptnetmap.acked_features = 0; + priv->ptnetmap.running = 0; + if (netmap_has_vnet_hdr_len(be, VNET_HDR_LEN)) { + priv->ptnetmap.features |= NET_PTN_FEATURES_VNET_HDR; + } + /* XXX Call ptn_memdev_attach() here or in get_ptnetmap ? */ + ptn_memdev_attach(priv->nmd->mem, priv->nmd->memsize, + priv->nmd->req.nr_arg2); + } + be->priv = priv; return 0; @@ -494,6 +641,9 @@ struct netmap_priv *priv = be->priv; if (be->priv) { + if (priv->ptnetmap.running) { + ptnetmap_delete(&priv->ptnetmap); + } nm_close(priv->nmd); free(be->priv); be->priv = NULL; @@ -741,11 +891,6 @@ be, be->name); be->set_features = netbe_null_set_features; } - if (be->get_ptnetmap == NULL) { - /*fprintf(stderr, "missing set_features for %p %s\n", - be, be->name);*/ - be->get_ptnetmap = netbe_null_get_ptnetmap; - } } /* @@ -836,9 +981,8 @@ return 0; /* There are only three valid lengths. */ - if (vnet_hdr_len && vnet_hdr_len != sizeof(struct virtio_net_rxhdr) - && vnet_hdr_len != (sizeof(struct virtio_net_rxhdr) - - sizeof(uint16_t))) + if (vnet_hdr_len && vnet_hdr_len != VNET_HDR_LEN + && vnet_hdr_len != (VNET_HDR_LEN - sizeof(uint16_t))) return -1; be->fe_vnet_hdr_len = vnet_hdr_len; @@ -919,7 +1063,7 @@ */ memset(vh, 0, hlen); - if (hlen == sizeof(struct virtio_net_rxhdr)) { + if (hlen == VNET_HDR_LEN) { vh->vrh_bufs = 1; } } Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 13:53:35 2016 (r307218) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 13:54:55 2016 (r307219) @@ -84,4 +84,33 @@ uint16_t vrh_bufs; } __packed; +/* + * ptnetmap definitions + */ +struct ptnetmap_state { + void *netmap_priv; + + /* True if ptnetmap kthreads are running. */ + int running; + + /* Feature acknoweledgement support. */ + unsigned long features; + unsigned long acked_features; + + /* Info about netmap memory. */ + uint32_t memsize; + void *mem; +}; + +/* Used to get read-only info. */ +struct netmap_if_info { + uint32_t nifp_offset; + uint16_t num_tx_rings; + uint16_t num_rx_rings; + uint16_t num_tx_slots; + uint16_t num_rx_slots; +}; + +int ptn_memdev_attach(void *mem_ptr, uint32_t mem_size, uint16_t mem_id); + #endif /* __NET_BACKENDS_H__ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201608051354.u75Dsuw1037808>