Deleted Added
full compact
netmap.c (228845) netmap.c (229939)
1/*
2 * Copyright (C) 2011 Matteo Landi, Luigi Rizzo. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 10 unchanged lines hidden (view full) ---

19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26/*
1/*
2 * Copyright (C) 2011 Matteo Landi, Luigi Rizzo. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 10 unchanged lines hidden (view full) ---

19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26/*
27 * $FreeBSD: head/sys/dev/netmap/netmap.c 228845 2011-12-23 16:03:57Z luigi $
27 * $FreeBSD: head/sys/dev/netmap/netmap.c 229939 2012-01-10 19:57:23Z luigi $
28 * $Id: netmap.c 9795 2011-12-02 11:39:08Z luigi $
29 *
30 * This module supports memory mapped access to network devices,
31 * see netmap(4).
32 *
33 * The module uses a large, memory pool allocated by the kernel
34 * and accessible as mmapped memory by multiple userspace threads/processes.
35 * The memory pool contains packet buffers and "netmap rings",

--- 15 unchanged lines hidden (view full) ---

51 * of the queue with the actual status in the kernel. This includes both
52 * receiving the notification of new packets, and transmitting new
53 * packets on the output interface.
54 * 6. select() or poll() can be used to wait for events on individual
55 * transmit or receive queues (or all queues for a given interface).
56 */
57
58#include <sys/cdefs.h> /* prerequisite */
28 * $Id: netmap.c 9795 2011-12-02 11:39:08Z luigi $
29 *
30 * This module supports memory mapped access to network devices,
31 * see netmap(4).
32 *
33 * The module uses a large, memory pool allocated by the kernel
34 * and accessible as mmapped memory by multiple userspace threads/processes.
35 * The memory pool contains packet buffers and "netmap rings",

--- 15 unchanged lines hidden (view full) ---

51 * of the queue with the actual status in the kernel. This includes both
52 * receiving the notification of new packets, and transmitting new
53 * packets on the output interface.
54 * 6. select() or poll() can be used to wait for events on individual
55 * transmit or receive queues (or all queues for a given interface).
56 */
57
58#include <sys/cdefs.h> /* prerequisite */
59__FBSDID("$FreeBSD: head/sys/dev/netmap/netmap.c 228845 2011-12-23 16:03:57Z luigi $");
59__FBSDID("$FreeBSD: head/sys/dev/netmap/netmap.c 229939 2012-01-10 19:57:23Z luigi $");
60
61#include <sys/types.h>
62#include <sys/module.h>
63#include <sys/errno.h>
64#include <sys/param.h> /* defines used in kernel.h */
65#include <sys/jail.h>
66#include <sys/kernel.h> /* types used in module initialization */
67#include <sys/conf.h> /* cdevsw struct */

--- 31 unchanged lines hidden (view full) ---

99 * according to what is avalable when the module is loaded.
100 * At the moment the block is contiguous, but we can easily
101 * restrict our demand to smaller units (16..64k)
102 */
103#define NETMAP_MEMORY_SIZE (64 * 1024 * PAGE_SIZE)
104static void * netmap_malloc(size_t size, const char *msg);
105static void netmap_free(void *addr, const char *msg);
106
60
61#include <sys/types.h>
62#include <sys/module.h>
63#include <sys/errno.h>
64#include <sys/param.h> /* defines used in kernel.h */
65#include <sys/jail.h>
66#include <sys/kernel.h> /* types used in module initialization */
67#include <sys/conf.h> /* cdevsw struct */

--- 31 unchanged lines hidden (view full) ---

99 * according to what is avalable when the module is loaded.
100 * At the moment the block is contiguous, but we can easily
101 * restrict our demand to smaller units (16..64k)
102 */
103#define NETMAP_MEMORY_SIZE (64 * 1024 * PAGE_SIZE)
104static void * netmap_malloc(size_t size, const char *msg);
105static void netmap_free(void *addr, const char *msg);
106
107#define netmap_if_malloc(len) netmap_malloc(len, "nifp")
108#define netmap_if_free(v) netmap_free((v), "nifp")
109
110#define netmap_ring_malloc(len) netmap_malloc(len, "ring")
111#define netmap_free_rings(na) \
112 netmap_free((na)->tx_rings[0].ring, "shadow rings");
113
107/*
108 * Allocator for a pool of packet buffers. For each buffer we have
109 * one entry in the bitmap to signal the state. Allocation scans
110 * the bitmap, but since this is done only on attach, we are not
111 * too worried about performance
112 * XXX if we need to allocate small blocks, a translation
113 * table is used both for kernel virtual address and physical
114 * addresses.
115 */
116struct netmap_buf_pool {
117 u_int total_buffers; /* total buffers. */
118 u_int free;
119 u_int bufsize;
120 char *base; /* buffer base address */
121 uint32_t *bitmap; /* one bit per buffer, 1 means free */
122};
123struct netmap_buf_pool nm_buf_pool;
124/* XXX move these two vars back into netmap_buf_pool */
125u_int netmap_total_buffers;
114/*
115 * Allocator for a pool of packet buffers. For each buffer we have
116 * one entry in the bitmap to signal the state. Allocation scans
117 * the bitmap, but since this is done only on attach, we are not
118 * too worried about performance
119 * XXX if we need to allocate small blocks, a translation
120 * table is used both for kernel virtual address and physical
121 * addresses.
122 */
123struct netmap_buf_pool {
124 u_int total_buffers; /* total buffers. */
125 u_int free;
126 u_int bufsize;
127 char *base; /* buffer base address */
128 uint32_t *bitmap; /* one bit per buffer, 1 means free */
129};
130struct netmap_buf_pool nm_buf_pool;
131/* XXX move these two vars back into netmap_buf_pool */
132u_int netmap_total_buffers;
126char *netmap_buffer_base;
133char *netmap_buffer_base; /* address of an invalid buffer */
127
128/* user-controlled variables */
129int netmap_verbose;
130
131static int no_timestamp; /* don't timestamp on rxsync */
132
133SYSCTL_NODE(_dev, OID_AUTO, netmap, CTLFLAG_RW, 0, "Netmap args");
134SYSCTL_INT(_dev_netmap, OID_AUTO, verbose,

--- 93 unchanged lines hidden (view full) ---

228 struct netmap_if *np_nifp; /* netmap interface descriptor. */
229
230 struct ifnet *np_ifp; /* device for which we hold a reference */
231 int np_ringid; /* from the ioctl */
232 u_int np_qfirst, np_qlast; /* range of rings to scan */
233 uint16_t np_txpoll;
234};
235
134
135/* user-controlled variables */
136int netmap_verbose;
137
138static int no_timestamp; /* don't timestamp on rxsync */
139
140SYSCTL_NODE(_dev, OID_AUTO, netmap, CTLFLAG_RW, 0, "Netmap args");
141SYSCTL_INT(_dev_netmap, OID_AUTO, verbose,

--- 93 unchanged lines hidden (view full) ---

235 struct netmap_if *np_nifp; /* netmap interface descriptor. */
236
237 struct ifnet *np_ifp; /* device for which we hold a reference */
238 int np_ringid; /* from the ioctl */
239 u_int np_qfirst, np_qlast; /* range of rings to scan */
240 uint16_t np_txpoll;
241};
242
243/* Shorthand to compute a netmap interface offset. */
244#define netmap_if_offset(v) \
245 ((char *) (v) - (char *) netmap_mem_d->nm_buffer)
246/* .. and get a physical address given a memory offset */
247#define netmap_ofstophys(o) \
248 (vtophys(netmap_mem_d->nm_buffer) + (o))
236
237static struct cdev *netmap_dev; /* /dev/netmap character device. */
238static struct netmap_mem_d *netmap_mem_d; /* Our memory allocator. */
239
240
241static d_mmap_t netmap_mmap;
242static d_ioctl_t netmap_ioctl;
243static d_poll_t netmap_poll;

--- 148 unchanged lines hidden (view full) ---

392 ND("rx queue %d", i);
393 ring = na->rx_rings[i].ring;
394 lim = na->rx_rings[i].nkr_num_slots;
395 for (j = 0; j < lim; j++)
396 netmap_free_buf(&nm_buf_pool,
397 ring->slot[j].buf_idx);
398 }
399 NMA_UNLOCK();
249
250static struct cdev *netmap_dev; /* /dev/netmap character device. */
251static struct netmap_mem_d *netmap_mem_d; /* Our memory allocator. */
252
253
254static d_mmap_t netmap_mmap;
255static d_ioctl_t netmap_ioctl;
256static d_poll_t netmap_poll;

--- 148 unchanged lines hidden (view full) ---

405 ND("rx queue %d", i);
406 ring = na->rx_rings[i].ring;
407 lim = na->rx_rings[i].nkr_num_slots;
408 for (j = 0; j < lim; j++)
409 netmap_free_buf(&nm_buf_pool,
410 ring->slot[j].buf_idx);
411 }
412 NMA_UNLOCK();
400 netmap_free(na->tx_rings[0].ring, "shadow rings");
413 netmap_free_rings(na);
401 wakeup(na);
402 }
414 wakeup(na);
415 }
403 netmap_free(nifp, "nifp");
416 netmap_if_free(nifp);
404
405 na->nm_lock(ifp->if_softc, NETMAP_CORE_UNLOCK, 0);
406
407 if_rele(ifp);
408
409 bzero(priv, sizeof(*priv)); /* XXX for safety */
410 free(priv, M_DEVBUF);
411}

--- 15 unchanged lines hidden (view full) ---

427 u_int i, len, ofs;
428 u_int n = na->num_queues + 1; /* shorthand, include stack queue */
429
430 /*
431 * the descriptor is followed inline by an array of offsets
432 * to the tx and rx rings in the shared memory region.
433 */
434 len = sizeof(struct netmap_if) + 2 * n * sizeof(ssize_t);
417
418 na->nm_lock(ifp->if_softc, NETMAP_CORE_UNLOCK, 0);
419
420 if_rele(ifp);
421
422 bzero(priv, sizeof(*priv)); /* XXX for safety */
423 free(priv, M_DEVBUF);
424}

--- 15 unchanged lines hidden (view full) ---

440 u_int i, len, ofs;
441 u_int n = na->num_queues + 1; /* shorthand, include stack queue */
442
443 /*
444 * the descriptor is followed inline by an array of offsets
445 * to the tx and rx rings in the shared memory region.
446 */
447 len = sizeof(struct netmap_if) + 2 * n * sizeof(ssize_t);
435 nifp = netmap_malloc(len, "nifp");
448 nifp = netmap_if_malloc(len);
436 if (nifp == NULL)
437 return (NULL);
438
439 /* initialize base fields */
440 *(int *)(uintptr_t)&nifp->ni_num_queues = na->num_queues;
441 strncpy(nifp->ni_name, ifname, IFNAMSIZ);
442
443 (na->refcount)++; /* XXX atomic ? we are under lock */

--- 6 unchanged lines hidden (view full) ---

450 * The rings are contiguous, but have variable size.
451 * The entire block is reachable at
452 * na->tx_rings[0].ring
453 */
454
455 len = n * (2 * sizeof(struct netmap_ring) +
456 (na->num_tx_desc + na->num_rx_desc) *
457 sizeof(struct netmap_slot) );
449 if (nifp == NULL)
450 return (NULL);
451
452 /* initialize base fields */
453 *(int *)(uintptr_t)&nifp->ni_num_queues = na->num_queues;
454 strncpy(nifp->ni_name, ifname, IFNAMSIZ);
455
456 (na->refcount)++; /* XXX atomic ? we are under lock */

--- 6 unchanged lines hidden (view full) ---

463 * The rings are contiguous, but have variable size.
464 * The entire block is reachable at
465 * na->tx_rings[0].ring
466 */
467
468 len = n * (2 * sizeof(struct netmap_ring) +
469 (na->num_tx_desc + na->num_rx_desc) *
470 sizeof(struct netmap_slot) );
458 buff = netmap_malloc(len, "shadow rings");
471 buff = netmap_ring_malloc(len);
459 if (buff == NULL) {
460 D("failed to allocate %d bytes for %s shadow ring",
461 len, ifname);
462error:
463 (na->refcount)--;
472 if (buff == NULL) {
473 D("failed to allocate %d bytes for %s shadow ring",
474 len, ifname);
475error:
476 (na->refcount)--;
464 netmap_free(nifp, "nifp, rings failed");
477 netmap_if_free(nifp);
465 return (NULL);
466 }
467 /* do we have the bufers ? we are in need of num_tx_desc buffers for
468 * each tx ring and num_tx_desc buffers for each rx ring. */
469 len = n * (na->num_tx_desc + na->num_rx_desc);
470 NMA_LOCK();
471 if (nm_buf_pool.free < len) {
472 NMA_UNLOCK();

--- 429 unchanged lines hidden (view full) ---

902 /* Otherwise set the card in netmap mode
903 * and make it use the shared buffers.
904 */
905 error = na->nm_register(ifp, 1); /* mode on */
906 if (error) {
907 /*
908 * do something similar to netmap_dtor().
909 */
478 return (NULL);
479 }
480 /* do we have the bufers ? we are in need of num_tx_desc buffers for
481 * each tx ring and num_tx_desc buffers for each rx ring. */
482 len = n * (na->num_tx_desc + na->num_rx_desc);
483 NMA_LOCK();
484 if (nm_buf_pool.free < len) {
485 NMA_UNLOCK();

--- 429 unchanged lines hidden (view full) ---

915 /* Otherwise set the card in netmap mode
916 * and make it use the shared buffers.
917 */
918 error = na->nm_register(ifp, 1); /* mode on */
919 if (error) {
920 /*
921 * do something similar to netmap_dtor().
922 */
910 netmap_free(na->tx_rings[0].ring, "rings, reg.failed");
911 free(na->tx_rings, M_DEVBUF);
923 netmap_free_rings(na);
924 // XXX tx_rings is inline, must not be freed.
925 // free(na->tx_rings, M_DEVBUF); // XXX wrong ?
912 na->tx_rings = na->rx_rings = NULL;
913 na->refcount--;
926 na->tx_rings = na->rx_rings = NULL;
927 na->refcount--;
914 netmap_free(nifp, "nifp, rings failed");
928 netmap_if_free(nifp);
915 nifp = NULL;
916 }
917 }
918
919 if (error) { /* reg. failed, release priv and ref */
920error:
921 na->nm_lock(adapter, NETMAP_CORE_UNLOCK, 0);
922 free(priv, M_DEVBUF);

--- 460 unchanged lines hidden (view full) ---

1383{
1384}
1385
1386/* unload a bus_dmamap and create a new one. Used when the
1387 * buffer in the slot is changed.
1388 * XXX buflen is probably not needed, buffers have constant size.
1389 */
1390void
929 nifp = NULL;
930 }
931 }
932
933 if (error) { /* reg. failed, release priv and ref */
934error:
935 na->nm_lock(adapter, NETMAP_CORE_UNLOCK, 0);
936 free(priv, M_DEVBUF);

--- 460 unchanged lines hidden (view full) ---

1397{
1398}
1399
1400/* unload a bus_dmamap and create a new one. Used when the
1401 * buffer in the slot is changed.
1402 * XXX buflen is probably not needed, buffers have constant size.
1403 */
1404void
1391netmap_reload_map(bus_dma_tag_t tag, bus_dmamap_t map,
1392 void *buf, bus_size_t buflen)
1405netmap_reload_map(bus_dma_tag_t tag, bus_dmamap_t map, void *buf)
1393{
1406{
1394 bus_addr_t paddr;
1395 bus_dmamap_unload(tag, map);
1407 bus_dmamap_unload(tag, map);
1396 bus_dmamap_load(tag, map, buf, buflen, ns_dmamap_cb, &paddr,
1397 BUS_DMA_NOWAIT);
1408 bus_dmamap_load(tag, map, buf, NETMAP_BUF_SIZE, ns_dmamap_cb,
1409 NULL, BUS_DMA_NOWAIT);
1398}
1399
1400void
1410}
1411
1412void
1401netmap_load_map(bus_dma_tag_t tag, bus_dmamap_t map,
1402 void *buf, bus_size_t buflen)
1413netmap_load_map(bus_dma_tag_t tag, bus_dmamap_t map, void *buf)
1403{
1414{
1404 bus_addr_t paddr;
1405 bus_dmamap_load(tag, map, buf, buflen, ns_dmamap_cb, &paddr,
1406 BUS_DMA_NOWAIT);
1415 bus_dmamap_load(tag, map, buf, NETMAP_BUF_SIZE, ns_dmamap_cb,
1416 NULL, BUS_DMA_NOWAIT);
1407}
1408
1409/*------ netmap memory allocator -------*/
1410/*
1411 * Request for a chunk of memory.
1412 *
1413 * Memory objects are arranged into a list, hence we need to walk this
1414 * list until we find an object with the needed amount of data free.

--- 291 unchanged lines hidden ---
1417}
1418
1419/*------ netmap memory allocator -------*/
1420/*
1421 * Request for a chunk of memory.
1422 *
1423 * Memory objects are arranged into a list, hence we need to walk this
1424 * list until we find an object with the needed amount of data free.

--- 291 unchanged lines hidden ---