qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Craig Boston <craig@yekse.gank.org>
To: nox@jelal.kn-bremen.de, antony.t.curtis@ntlworld.com
Cc: qemu-devel@nongnu.org
Subject: [Qemu-devel] KQemu FreeBSD wrapper cloning support
Date: Fri, 10 Jun 2005 22:42:09 -0500	[thread overview]
Message-ID: <20050611034209.GA3948@nowhere> (raw)

[-- Attachment #1: Type: text/plain, Size: 894 bytes --]

Hello,

Attached is an experimental patch I threw together this evening that
adds support for FreeBSD 5.x+ device cloning to Antony's kqemu wrapper.

I haven't done just a whole lot of testing, but it passes the "works for
me" test.  With it I'm able to load the module, start up a few
concurrent qemu instances (all using the accelerator), close some, open
one or two more, then close them all and unload the module.

So far the only problem I've run into is a panic if you repeatedly ls -l
/dev/kqemu and /dev/kqemu[0-9].  However, I am able to cause the same
panic by doing that with the tun device, so it appears to be a bug in
FreeBSD (possibly specific to 6.0-current).

It still has the 4 instance limit, which appears to have been copied
from the Linux module.  I debated removing it, but figured there must be
some reason it's in there...

Just thought you might be interested.

Craig

[-- Attachment #2: kmod_bsd_clone.patch --]
[-- Type: text/plain, Size: 4060 bytes --]

--- kmod_bsd.c.orig	Fri Jun 10 19:14:08 2005
+++ kmod_bsd.c	Fri Jun 10 22:27:13 2005
@@ -284,6 +284,10 @@
 #define KQEMU_MAX_INSTANCES 4
 
 struct kqemu_instance {
+#if __FreeBSD_version > 500000
+    TAILQ_ENTRY(kqemu_instance) kqemu_ent;
+    struct cdev *kqemu_dev;
+#endif
     struct kqemu_state *state;
 };
 
@@ -292,7 +296,9 @@
 #if __FreeBSD_version < 500000
 static dev_t kqemu_dev;
 #else
-static struct cdev *kqemu_dev;
+static struct clonedevs *kqemuclones;
+static TAILQ_HEAD(,kqemu_instance) kqemuhead = TAILQ_HEAD_INITIALIZER(kqemuhead);
+static eventhandler_tag clonetag;
 #endif
 
 
@@ -325,6 +331,61 @@
 #endif
 };
 
+#if __FreeBSD_version > 500000
+static void
+kqemu_clone(void *arg, char *name, int namelen, struct cdev **dev)
+{
+    int unit, r;
+    if (*dev != NULL)
+	return;
+
+    if (strcmp(name, "kqemu") == 0)
+	unit = -1;
+    else if (dev_stdclone(name, NULL, "kqemu", &unit) != 1)
+	return;		/* Bad name */
+    if (unit != -1 && unit > KQEMU_MAX_INSTANCES)
+	return;
+
+    r = clone_create(&kqemuclones, &kqemu_cdevsw, &unit, dev, 0);
+    if (r) {
+	    *dev = make_dev(&kqemu_cdevsw, unit2minor(unit),
+		    UID_ROOT, GID_WHEEL, 0660, "kqemu%d", unit);
+	    if (*dev != NULL) {
+		    dev_ref(*dev);
+		    (*dev)->si_flags |= SI_CHEAPCLONE;
+	    }
+    }
+}
+#endif
+
+static void kqemu_destroy(struct kqemu_instance *ks)
+{
+    struct cdev *dev = ks->kqemu_dev;
+
+    if (ks->state) {
+	kqemu_delete(ks->state);
+	ks->state = NULL;
+    }
+
+    free(ks, M_KQEMU);
+    dev->si_drv1 = NULL;
+#if __FreeBSD_version > 500000
+    mtx_lock_spin(&cache_lock);
+    TAILQ_REMOVE(&kqemuhead, ks, kqemu_ent);
+#endif
+    if (!--kqemu_ref_count) {
+	int i;
+	for (i = 1023; i >= 0; i--)
+	    kqemu_vfree(pagecache[i]);
+        memset(pagecache, 0, 1024 * sizeof(void *));
+    }
+#if __FreeBSD_version > 500000
+    mtx_unlock_spin(&cache_lock);
+
+    destroy_dev(dev);
+#endif
+}
+
 int
 #if __FreeBSD_version < 500000
 kqemu_open(dev, flags, fmt, p)
@@ -355,7 +416,9 @@
     
     dev->si_drv1 = ks;
 #if __FreeBSD_version > 500000
+    ks->kqemu_dev = dev;
     mtx_lock_spin(&cache_lock);
+    TAILQ_INSERT_TAIL(&kqemuhead, ks, kqemu_ent);
 #endif
     kqemu_ref_count++;
 #if __FreeBSD_version > 500000
@@ -382,25 +445,8 @@
 #endif
     struct kqemu_instance *ks = (struct kqemu_instance *) dev->si_drv1;
 
-    if (ks->state) {
-	kqemu_delete(ks->state);
-	ks->state = NULL;
-    }
-    
-    free(ks, M_KQEMU);
-    dev->si_drv1 = NULL;
-#if __FreeBSD_version > 500000
-    mtx_lock_spin(&cache_lock);
-#endif
-    if (!--kqemu_ref_count) {
-	int i;
-	for (i = 1023; i >= 0; i--)
-	    kqemu_vfree(pagecache[i]);
-        memset(pagecache, 0, 1024 * sizeof(void *));
-    }
-#if __FreeBSD_version > 500000
-    mtx_unlock_spin(&cache_lock);
-#endif
+    kqemu_destroy(ks);
+
     kqemu_log("closed by pid=%d\n", p->p_pid);
     return(0);
 }
@@ -513,9 +559,14 @@
     	kqemu_log("error registering cdevsw, rc=%d\n", rc);
 	return(ENOENT);
     }
-#endif
 	
     kqemu_dev = make_dev(&kqemu_cdevsw, 0, UID_ROOT, GID_WHEEL, 0660, "kqemu");
+#else
+    clone_setup(&kqemuclones);
+    clonetag = EVENTHANDLER_REGISTER(dev_clone, kqemu_clone, 0, 1000);
+    if (!clonetag)
+	return ENOMEM;
+#endif
 
     kqemu_log("KQEMU installed, max_instances=%d max_locked_mem=%dkB.\n",
               KQEMU_MAX_INSTANCES, max_locked_pages * 4);
@@ -529,12 +580,25 @@
 {
 #if __FreeBSD_version < 500000
     int rc;
+#else
+    struct kqemu_instance *ks;
 #endif
     
-    destroy_dev(kqemu_dev);
 #if __FreeBSD_version < 500000
+    destroy_dev(kqemu_dev);
     if ((rc = cdevsw_remove(&kqemu_cdevsw)))
 	kqemu_log("error unregistering, rc=%d\n", rc);
+#else
+    EVENTHANDLER_DEREGISTER(dev_clone, clonetag);
+    mtx_lock_spin(&cache_lock);
+    while ((ks = TAILQ_FIRST(&kqemuhead)) != NULL) {
+	mtx_unlock_spin(&cache_lock);
+	kqemu_destroy(ks);
+	mtx_lock_spin(&cache_lock);
+    }
+    mtx_unlock_spin(&cache_lock);
+    mtx_destroy(&cache_lock);
+    clone_cleanup(&kqemuclones);
 #endif
 
     kqemu_vfree(pagecache);

                 reply	other threads:[~2005-06-11  4:05 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050611034209.GA3948@nowhere \
    --to=craig@yekse.gank.org \
    --cc=antony.t.curtis@ntlworld.com \
    --cc=nox@jelal.kn-bremen.de \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).