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).