netmap_freebsd.c (279199) | netmap_freebsd.c (285349) |
---|---|
1/* 2 * Copyright (C) 2013-2014 Universita` di Pisa. 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. --- 9 unchanged lines hidden (view full) --- 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 | 1/* 2 * Copyright (C) 2013-2014 Universita` di Pisa. 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. --- 9 unchanged lines hidden (view full) --- 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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/* $FreeBSD: head/sys/dev/netmap/netmap_freebsd.c 279199 2015-02-23 07:28:31Z luigi $ */ | 26/* $FreeBSD: head/sys/dev/netmap/netmap_freebsd.c 285349 2015-07-10 05:51:36Z luigi $ */ 27#include "opt_inet.h" 28#include "opt_inet6.h" |
27 28#include <sys/types.h> 29#include <sys/module.h> 30#include <sys/errno.h> 31#include <sys/param.h> /* defines used in kernel.h */ 32#include <sys/poll.h> /* POLLIN, POLLOUT */ 33#include <sys/kernel.h> /* types used in module initialization */ 34#include <sys/conf.h> /* DEV_MODULE */ --- 108 unchanged lines hidden (view full) --- 143} 144 145 146/* 147 * Intercept the rx routine in the standard device driver. 148 * Second argument is non-zero to intercept, 0 to restore 149 */ 150int | 29 30#include <sys/types.h> 31#include <sys/module.h> 32#include <sys/errno.h> 33#include <sys/param.h> /* defines used in kernel.h */ 34#include <sys/poll.h> /* POLLIN, POLLOUT */ 35#include <sys/kernel.h> /* types used in module initialization */ 36#include <sys/conf.h> /* DEV_MODULE */ --- 108 unchanged lines hidden (view full) --- 145} 146 147 148/* 149 * Intercept the rx routine in the standard device driver. 150 * Second argument is non-zero to intercept, 0 to restore 151 */ 152int |
151netmap_catch_rx(struct netmap_adapter *na, int intercept) | 153netmap_catch_rx(struct netmap_generic_adapter *gna, int intercept) |
152{ | 154{ |
153 struct netmap_generic_adapter *gna = (struct netmap_generic_adapter *)na; | 155 struct netmap_adapter *na = &gna->up.up; |
154 struct ifnet *ifp = na->ifp; 155 156 if (intercept) { 157 if (gna->save_if_input) { 158 D("cannot intercept again"); 159 return EINVAL; /* already set */ 160 } 161 gna->save_if_input = ifp->if_input; --- 16 unchanged lines hidden (view full) --- 178 * so that we can decide which queue is used for an mbuf. 179 * Second argument is non-zero to intercept, 0 to restore. 180 * On freebsd we just intercept if_transmit. 181 */ 182void 183netmap_catch_tx(struct netmap_generic_adapter *gna, int enable) 184{ 185 struct netmap_adapter *na = &gna->up.up; | 156 struct ifnet *ifp = na->ifp; 157 158 if (intercept) { 159 if (gna->save_if_input) { 160 D("cannot intercept again"); 161 return EINVAL; /* already set */ 162 } 163 gna->save_if_input = ifp->if_input; --- 16 unchanged lines hidden (view full) --- 180 * so that we can decide which queue is used for an mbuf. 181 * Second argument is non-zero to intercept, 0 to restore. 182 * On freebsd we just intercept if_transmit. 183 */ 184void 185netmap_catch_tx(struct netmap_generic_adapter *gna, int enable) 186{ 187 struct netmap_adapter *na = &gna->up.up; |
186 struct ifnet *ifp = na->ifp; | 188 struct ifnet *ifp = netmap_generic_getifp(gna); |
187 188 if (enable) { 189 na->if_transmit = ifp->if_transmit; 190 ifp->if_transmit = netmap_transmit; 191 } else { 192 ifp->if_transmit = na->if_transmit; 193 } 194} --- 294 unchanged lines hidden (view full) --- 489 490 491static int 492netmap_dev_pager_fault(vm_object_t object, vm_ooffset_t offset, 493 int prot, vm_page_t *mres) 494{ 495 struct netmap_vm_handle_t *vmh = object->handle; 496 struct netmap_priv_d *priv = vmh->priv; | 189 190 if (enable) { 191 na->if_transmit = ifp->if_transmit; 192 ifp->if_transmit = netmap_transmit; 193 } else { 194 ifp->if_transmit = na->if_transmit; 195 } 196} --- 294 unchanged lines hidden (view full) --- 491 492 493static int 494netmap_dev_pager_fault(vm_object_t object, vm_ooffset_t offset, 495 int prot, vm_page_t *mres) 496{ 497 struct netmap_vm_handle_t *vmh = object->handle; 498 struct netmap_priv_d *priv = vmh->priv; |
499 struct netmap_adapter *na = priv->np_na; |
|
497 vm_paddr_t paddr; 498 vm_page_t page; 499 vm_memattr_t memattr; 500 vm_pindex_t pidx; 501 502 ND("object %p offset %jd prot %d mres %p", 503 object, (intmax_t)offset, prot, mres); 504 memattr = object->memattr; 505 pidx = OFF_TO_IDX(offset); | 500 vm_paddr_t paddr; 501 vm_page_t page; 502 vm_memattr_t memattr; 503 vm_pindex_t pidx; 504 505 ND("object %p offset %jd prot %d mres %p", 506 object, (intmax_t)offset, prot, mres); 507 memattr = object->memattr; 508 pidx = OFF_TO_IDX(offset); |
506 paddr = netmap_mem_ofstophys(priv->np_mref, offset); | 509 paddr = netmap_mem_ofstophys(na->nm_mem, offset); |
507 if (paddr == 0) 508 return VM_PAGER_FAIL; 509 510 if (((*mres)->flags & PG_FICTITIOUS) != 0) { 511 /* 512 * If the passed in result page is a fake page, update it with 513 * the new physical address. 514 */ --- 48 unchanged lines hidden (view full) --- 563 if (vmh == NULL) 564 return ENOMEM; 565 vmh->dev = cdev; 566 567 NMG_LOCK(); 568 error = devfs_get_cdevpriv((void**)&priv); 569 if (error) 570 goto err_unlock; | 510 if (paddr == 0) 511 return VM_PAGER_FAIL; 512 513 if (((*mres)->flags & PG_FICTITIOUS) != 0) { 514 /* 515 * If the passed in result page is a fake page, update it with 516 * the new physical address. 517 */ --- 48 unchanged lines hidden (view full) --- 566 if (vmh == NULL) 567 return ENOMEM; 568 vmh->dev = cdev; 569 570 NMG_LOCK(); 571 error = devfs_get_cdevpriv((void**)&priv); 572 if (error) 573 goto err_unlock; |
574 if (priv->np_nifp == NULL) { 575 error = EINVAL; 576 goto err_unlock; 577 } |
|
571 vmh->priv = priv; 572 priv->np_refcount++; 573 NMG_UNLOCK(); 574 | 578 vmh->priv = priv; 579 priv->np_refcount++; 580 NMG_UNLOCK(); 581 |
575 error = netmap_get_memory(priv); 576 if (error) 577 goto err_deref; 578 | |
579 obj = cdev_pager_allocate(vmh, OBJT_DEVICE, 580 &netmap_cdev_pager_ops, objsize, prot, 581 *foff, NULL); 582 if (obj == NULL) { 583 D("cdev_pager_allocate failed"); 584 error = EINVAL; 585 goto err_deref; 586 } --- 6 unchanged lines hidden (view full) --- 593 priv->np_refcount--; 594err_unlock: 595 NMG_UNLOCK(); 596// err: 597 free(vmh, M_DEVBUF); 598 return error; 599} 600 | 582 obj = cdev_pager_allocate(vmh, OBJT_DEVICE, 583 &netmap_cdev_pager_ops, objsize, prot, 584 *foff, NULL); 585 if (obj == NULL) { 586 D("cdev_pager_allocate failed"); 587 error = EINVAL; 588 goto err_deref; 589 } --- 6 unchanged lines hidden (view full) --- 596 priv->np_refcount--; 597err_unlock: 598 NMG_UNLOCK(); 599// err: 600 free(vmh, M_DEVBUF); 601 return error; 602} 603 |
601 602// XXX can we remove this ? | 604/* 605 * netmap_close() is called on every close(), but we do not need to do 606 * anything at that moment, since the process may have other open file 607 * descriptors for /dev/netmap. Instead, we pass netmap_dtor() to 608 * devfs_set_cdevpriv() on open(). The FreeBSD kernel will call the destructor 609 * when the last fd pointing to the device is closed. 610 * 611 * Unfortunately, FreeBSD does not automatically track active mmap()s on an fd, 612 * so we have to track them by ourselvesi (see above). The result is that 613 * netmap_dtor() is called when the process has no open fds and no active 614 * memory maps on /dev/netmap, as in linux. 615 */ |
603static int 604netmap_close(struct cdev *dev, int fflag, int devtype, struct thread *td) 605{ 606 if (netmap_verbose) 607 D("dev %p fflag 0x%x devtype %d td %p", 608 dev, fflag, devtype, td); 609 return 0; 610} --- 57 unchanged lines hidden (view full) --- 668 */ 669 KNOTE_UNLOCKED(&si->si.si_note, 0x100 /* notification */); 670} 671 672static void 673netmap_knrdetach(struct knote *kn) 674{ 675 struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook; | 616static int 617netmap_close(struct cdev *dev, int fflag, int devtype, struct thread *td) 618{ 619 if (netmap_verbose) 620 D("dev %p fflag 0x%x devtype %d td %p", 621 dev, fflag, devtype, td); 622 return 0; 623} --- 57 unchanged lines hidden (view full) --- 681 */ 682 KNOTE_UNLOCKED(&si->si.si_note, 0x100 /* notification */); 683} 684 685static void 686netmap_knrdetach(struct knote *kn) 687{ 688 struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook; |
676 struct selinfo *si = &priv->np_rxsi->si; | 689 struct selinfo *si = &priv->np_si[NR_RX]->si; |
677 678 D("remove selinfo %p", si); 679 knlist_remove(&si->si_note, kn, 0); 680} 681 682static void 683netmap_knwdetach(struct knote *kn) 684{ 685 struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook; | 690 691 D("remove selinfo %p", si); 692 knlist_remove(&si->si_note, kn, 0); 693} 694 695static void 696netmap_knwdetach(struct knote *kn) 697{ 698 struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook; |
686 struct selinfo *si = &priv->np_txsi->si; | 699 struct selinfo *si = &priv->np_si[NR_TX]->si; |
687 688 D("remove selinfo %p", si); 689 knlist_remove(&si->si_note, kn, 0); 690} 691 692/* 693 * callback from notifies (generated externally) and our 694 * calls to kevent(). The former we just return 1 (ready) --- 73 unchanged lines hidden (view full) --- 768 return 1; 769 } 770 na = priv->np_na; 771 if (na == NULL) { 772 D("no netmap adapter for this file descriptor"); 773 return 1; 774 } 775 /* the si is indicated in the priv */ | 700 701 D("remove selinfo %p", si); 702 knlist_remove(&si->si_note, kn, 0); 703} 704 705/* 706 * callback from notifies (generated externally) and our 707 * calls to kevent(). The former we just return 1 (ready) --- 73 unchanged lines hidden (view full) --- 781 return 1; 782 } 783 na = priv->np_na; 784 if (na == NULL) { 785 D("no netmap adapter for this file descriptor"); 786 return 1; 787 } 788 /* the si is indicated in the priv */ |
776 si = (ev == EVFILT_WRITE) ? priv->np_txsi : priv->np_rxsi; | 789 si = priv->np_si[(ev == EVFILT_WRITE) ? NR_TX : NR_RX]; |
777 // XXX lock(priv) ? 778 kn->kn_fop = (ev == EVFILT_WRITE) ? 779 &netmap_wfiltops : &netmap_rfiltops; 780 kn->kn_hook = priv; 781 knlist_add(&si->si.si_note, kn, 1); 782 // XXX unlock(priv) 783 ND("register %p %s td %p priv %p kn %p np_nifp %p kn_fp/fpop %s", 784 na, na->ifp->if_xname, curthread, priv, kn, --- 49 unchanged lines hidden --- | 790 // XXX lock(priv) ? 791 kn->kn_fop = (ev == EVFILT_WRITE) ? 792 &netmap_wfiltops : &netmap_rfiltops; 793 kn->kn_hook = priv; 794 knlist_add(&si->si.si_note, kn, 1); 795 // XXX unlock(priv) 796 ND("register %p %s td %p priv %p kn %p np_nifp %p kn_fp/fpop %s", 797 na, na->ifp->if_xname, curthread, priv, kn, --- 49 unchanged lines hidden --- |