summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorluigi <luigi@FreeBSD.org>2015-07-19 18:07:25 +0000
committerluigi <luigi@FreeBSD.org>2015-07-19 18:07:25 +0000
commit1e6fb0ec0941434282ebd1d79e32855a94caa1d5 (patch)
tree53c257919e0af2de1b7a21f03661e4e25c7e744e
parent2ab5dcebf29388e6d1a245cf4b8564e428775c6c (diff)
downloadFreeBSD-src-1e6fb0ec0941434282ebd1d79e32855a94caa1d5.zip
FreeBSD-src-1e6fb0ec0941434282ebd1d79e32855a94caa1d5.tar.gz
add a use count so the netmap module cannot be unloaded while in use.
-rw-r--r--sys/dev/netmap/netmap.c5
-rw-r--r--sys/dev/netmap/netmap_freebsd.c14
-rw-r--r--sys/dev/netmap/netmap_kern.h1
3 files changed, 18 insertions, 2 deletions
diff --git a/sys/dev/netmap/netmap.c b/sys/dev/netmap/netmap.c
index 60a3172..8094fe3 100644
--- a/sys/dev/netmap/netmap.c
+++ b/sys/dev/netmap/netmap.c
@@ -542,6 +542,7 @@ SYSCTL_INT(_dev_netmap, OID_AUTO, generic_ringsize, CTLFLAG_RW, &netmap_generic_
SYSCTL_INT(_dev_netmap, OID_AUTO, generic_rings, CTLFLAG_RW, &netmap_generic_rings, 0 , "");
NMG_LOCK_T netmap_global_lock;
+int netmap_use_count = 0; /* number of active netmap instances */
/*
* mark the ring as stopped, and run through the locks
@@ -975,11 +976,11 @@ netmap_dtor_locked(struct netmap_priv_d *priv)
{
struct netmap_adapter *na = priv->np_na;
- /* number of active mmaps on this fd (FreeBSD only) */
+ /* number of active references to this fd */
if (--priv->np_refs > 0) {
return 0;
}
-
+ netmap_use_count--;
if (!na) {
return 1; //XXX is it correct?
}
diff --git a/sys/dev/netmap/netmap_freebsd.c b/sys/dev/netmap/netmap_freebsd.c
index 31c7cf0..8490ae8 100644
--- a/sys/dev/netmap/netmap_freebsd.c
+++ b/sys/dev/netmap/netmap_freebsd.c
@@ -642,6 +642,10 @@ netmap_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
error = devfs_set_cdevpriv(priv, netmap_dtor);
if (error) {
free(priv, M_DEVBUF);
+ } else {
+ NMG_LOCK();
+ netmap_use_count++;
+ NMG_UNLOCK();
}
return error;
}
@@ -827,6 +831,16 @@ netmap_loader(__unused struct module *module, int event, __unused void *arg)
break;
case MOD_UNLOAD:
+ /*
+ * if some one is still using netmap,
+ * then the module can not be unloaded.
+ */
+ if (netmap_use_count) {
+ D("netmap module can not be unloaded - netmap_use_count: %d",
+ netmap_use_count);
+ error = EBUSY;
+ break;
+ }
netmap_fini();
break;
diff --git a/sys/dev/netmap/netmap_kern.h b/sys/dev/netmap/netmap_kern.h
index b46050d..d38b3b2 100644
--- a/sys/dev/netmap/netmap_kern.h
+++ b/sys/dev/netmap/netmap_kern.h
@@ -1247,6 +1247,7 @@ extern int netmap_txsync_retry;
extern int netmap_generic_mit;
extern int netmap_generic_ringsize;
extern int netmap_generic_rings;
+extern int netmap_use_count;
/*
* NA returns a pointer to the struct netmap adapter from the ifp,
OpenPOWER on IntegriCloud