Page MenuHomeFreeBSD

D3014.id6754.diff
No OneTemporary

D3014.id6754.diff

Index: tests/sys/vm/pmap/Makefile
===================================================================
--- /dev/null
+++ tests/sys/vm/pmap/Makefile
@@ -0,0 +1,5 @@
+SRCS=qpage.c
+KMOD=qpage
+
+.include <bsd.kmod.mk>
+
Index: tests/sys/vm/pmap/qpage.c
===================================================================
--- /dev/null
+++ tests/sys/vm/pmap/qpage.c
@@ -0,0 +1,163 @@
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/libkern.h>
+#include <sys/kthread.h>
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+#include <vm/pmap.h>
+
+static MALLOC_DEFINE(M_QMAP, "qmap", "qmap buffers");
+
+#define QMAP_NBUFS 2
+
+static struct thread *qmap_thrs[QMAP_NBUFS] = {NULL};
+
+static bool pass = true;
+
+struct qmap_buffer {
+ vm_page_t page;
+ struct mtx lock;
+ bool ready;
+ bool acked;
+};
+
+static struct qmap_buffer qmap_bufs[QMAP_NBUFS];
+
+struct qmap_thread_arg {
+ struct qmap_buffer *write_buf;
+ struct qmap_buffer *read_buf;
+ unsigned int loops;
+ bool stop;
+ bool exit;
+};
+
+static struct qmap_thread_arg thread_args[QMAP_NBUFS];
+
+static void
+qmap_thread(void *context)
+{
+ struct qmap_thread_arg *arg = context;
+ uint8_t fill = 0;
+
+ for (;;) {
+ vm_offset_t buf;
+ int i;
+
+ mtx_lock(&(arg->write_buf->lock));
+ if (!arg->stop && !arg->write_buf->acked)
+ mtx_sleep(&(arg->write_buf->acked), &(arg->write_buf->lock), 0, "qmap_write", 0);
+ arg->write_buf->acked = false;
+ if (!arg->stop) {
+ buf = pmap_quick_enter_page(arg->write_buf->page);
+ memset((void*)buf, (int)fill, PAGE_SIZE);
+ pmap_quick_remove_page(buf);
+ arg->write_buf->ready = true;
+ wakeup(&(arg->write_buf->ready));
+ }
+ mtx_unlock(&(arg->write_buf->lock));
+
+ mtx_lock(&(arg->read_buf->lock));
+ if (!arg->exit && !arg->read_buf->ready)
+ mtx_sleep(&(arg->read_buf->ready), &(arg->read_buf->lock), 0, "qmap_read", 0);
+ arg->read_buf->ready = false;
+ if (arg->exit) {
+ mtx_unlock(&(arg->read_buf->lock));
+ kthread_exit();
+ }
+ buf = pmap_quick_enter_page(arg->read_buf->page);
+ for (i = 0; i < PAGE_SIZE; ++i)
+ {
+ if (((uint8_t*)buf)[i] != fill)
+ {
+ pass = false;
+ break;
+ }
+ }
+ pmap_quick_remove_page(buf);
+ arg->read_buf->acked = true;
+ wakeup(&(arg->read_buf->acked));
+ mtx_unlock(&(arg->read_buf->lock));
+ if (i < PAGE_SIZE)
+ printf("Expected value 0x%x at buffer[%d]\n", fill, i);
+ ++fill;
+ ++(arg->loops);
+ }
+}
+
+static void
+qmap_mod_cleanup()
+{
+ for (int i = 0; i < QMAP_NBUFS; ++i) {
+ mtx_lock(&(thread_args[i].write_buf->lock));
+ thread_args[i].stop = true;
+ wakeup(&(thread_args[i].write_buf->acked));
+ mtx_unlock(&(thread_args[i].write_buf->lock));
+ mtx_lock(&(thread_args[i].read_buf->lock));
+ thread_args[i].exit = true;
+ wakeup(&(thread_args[i].read_buf->ready));
+ mtx_sleep(qmap_thrs[i], &(thread_args[i].read_buf->lock), 0, "qmap_join", 0);
+ mtx_unlock(&(thread_args[i].read_buf->lock));
+ }
+ for (int i = 0; i < QMAP_NBUFS; ++i) {
+ if (qmap_bufs[i].page != NULL) {
+ vm_page_unwire(qmap_bufs[i].page, PQ_INACTIVE);
+ vm_page_free(qmap_bufs[i].page);
+ }
+ mtx_destroy(&(qmap_bufs[i].lock));
+ }
+}
+
+static int
+qmap_mod_handler(module_t mod, int what, void *arg)
+{
+ int ret = 0;
+
+ switch(what) {
+ case MOD_LOAD:
+ for (int i = 0; i < QMAP_NBUFS; ++i) {
+ qmap_bufs[i].ready = false;
+ qmap_bufs[i].acked = true;
+ mtx_init(&(qmap_bufs[i].lock), "qmap test lock", NULL, MTX_DEF);
+ qmap_bufs[i].page = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED);
+ if (qmap_bufs[i].page == NULL)
+ ret = ENOMEM;
+ }
+ thread_args[0].write_buf = &qmap_bufs[0];
+ thread_args[0].read_buf = &qmap_bufs[1];
+ thread_args[0].stop = false;
+ thread_args[0].exit = false;
+ thread_args[0].loops = 0;
+ thread_args[1].write_buf = &qmap_bufs[1];
+ thread_args[1].read_buf = &qmap_bufs[0];
+ thread_args[1].stop = false;
+ thread_args[1].exit = false;
+ thread_args[1].loops = 0;
+ for (int i = 0; i < QMAP_NBUFS && ret == 0; ++i)
+ ret = kthread_add(&qmap_thread, &thread_args[i], NULL, &qmap_thrs[i], 0, 0, "qmap_thread[%d]", i);
+ if (ret != 0)
+ qmap_mod_cleanup();
+ return ret;
+ case MOD_UNLOAD:
+ case MOD_SHUTDOWN:
+ qmap_mod_cleanup();
+ printf("Ran %u,%u loops; result: %s\n", thread_args[0].loops,
+ thread_args[1].loops, (pass ? "PASS" : "FAIL"));
+ return 0;
+ default:
+ return 0;
+ }
+}
+
+static moduledata_t qmap_mod_data = {
+ "qmap",
+ qmap_mod_handler,
+ NULL
+};
+
+DECLARE_MODULE(qmap, qmap_mod_data, SI_SUB_DRIVERS, SI_ORDER_ANY);
+MODULE_VERSION(qmap, 1);

File Metadata

Mime Type
text/plain
Expires
Thu, Sep 3, 2:19 PM (55 m, 13 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38117550
Default Alt Text
D3014.id6754.diff (4 KB)

Event Timeline