]> xenbits.xensource.com Git - xentesttools/bootstrap.git/commitdiff
tmem-test: Initial work.
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Tue, 25 Aug 2015 15:22:10 +0000 (11:22 -0400)
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Wed, 26 Aug 2015 16:27:34 +0000 (12:27 -0400)
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
root_image/Makefile
root_image/drivers/Makefile
root_image/drivers/tmem_test/Makefile [new file with mode: 0644]
root_image/drivers/tmem_test/tmem_test.c [new file with mode: 0644]
root_image/etc/init.d/rcS
root_image/etc/init.d/tmem [new file with mode: 0755]

index 78104b7fbba6dc57c4510de029d582c74009485d..174cea720ebbb15161864180b8337745e0049f30 100644 (file)
@@ -472,9 +472,6 @@ endif
        $(call RPM_TO_USERSPACE,./sbin/fdisk,$(RPM_DIR)/util-linux-ng)
        $(call RPM_TO_USERSPACE,./sbin/losetup,$(RPM_DIR)/util-linux-ng)
        $(call RPM_TO_USERSPACE,./sbin/pivot_root,$(RPM_DIR)/util-linux-ng)
-       $(call RPM_TO_USERSPACE,./sbin/swapon,$(RPM_DIR)/util-linux-ng)
-       $(call RPM_TO_USERSPACE,./sbin/swapoff,$(RPM_DIR)/util-linux-ng)
-       $(call RPM_TO_USERSPACE,./sbin/mkswap,$(RPM_DIR)/util-linux-ng)
        $(call RPM_TO_USERSPACE,./usr/bin/hexdump,$(RPM_DIR)/util-linux-ng)
        $(call RPM_TO_USERSPACE,./usr/bin/flock,$(RPM_DIR)/util-linux-ng)
        $(call RPM_TO_USERSPACE,./usr/bin/time,$(RPM_DIR)/time)
@@ -974,8 +971,16 @@ xtt-tools-install-fb: directfb-install
        LDLIBS="-L$(shell pwd)/userspace/$(LIBSDIR)" $(MAKE) -j$$(($(NCPUS) * 2)) $(MFLAGS) -C tools/drfb_test
        $(INSTALL_PROG)   tools/drfb_test/dfbtest_fillrect     userspace/usr/bin/
 
+.PHONY: xtt-tools-install-eatmem
+xtt-tools-install-eatmem:
+       LDLIBS="-L$(shell pwd)/userspace/$(LIBSDIR)" $(MAKE) -j$$(($(NCPUS) * 2)) $(MFLAGS) -C tools/eatmem
+       $(call RPM_TO_USERSPACE,./sbin/mkswap,$(RPM_DIR)/util-linux-ng)
+       $(call RPM_TO_USERSPACE,./sbin/swapon,$(RPM_DIR)/util-linux-ng)
+       $(call RPM_TO_USERSPACE,./sbin/swapoff,$(RPM_DIR)/util-linux-ng)
+       $(INSTALL_PROG)   tools/eatmem/eatmem     userspace/usr/bin/
+
 .PHONY: xtt-tools-install
-xtt-tools-install:
+xtt-tools-install: xtt-tools-install-eatmem
        LDLIBS="-L$(shell pwd)/userspace/$(LIBSDIR)" $(MAKE) -j$$(($(NCPUS) * 2)) $(MFLAGS) -C tools
        $(INSTALL_PROG)   tools/ssh_support/ssh-shadowgen     userspace/usr/sbin/
        $(INSTALL_SCRIPT) tools/ssh_support/sshd_server       userspace/usr/bin/
@@ -986,7 +991,6 @@ xtt-tools-install:
        $(INSTALL_PROG)   tools/read_intr/read_intr     userspace/usr/bin/
        $(INSTALL_PROG)   tools/debug/fb_test     userspace/usr/bin/
        $(INSTALL_PROG)   tools/crashme/crashme     userspace/usr/bin/
-       $(INSTALL_PROG)   tools/eatmem/eatmem     userspace/usr/bin/
        $(INSTALL_PROG)   tools/discard_io/discard_io     userspace/usr/bin/
 
 fio/fio: fio/fio
index 209a3c3eb9eb7dd7a5f0eed86832924bdf9a66d9..45d68e16290d82dc62a1f72e41a4140bccb31f2b 100644 (file)
@@ -2,6 +2,7 @@ obj-m += dma_test/
 obj-m += wb_to_wc/
 obj-m += xen_diag/
 obj-m += spinlock_hog/
+obj-m += tmem_test/
 
 .PHONY:        distclean
 distclean:     clean
diff --git a/root_image/drivers/tmem_test/Makefile b/root_image/drivers/tmem_test/Makefile
new file mode 100644 (file)
index 0000000..4a02fb4
--- /dev/null
@@ -0,0 +1,37 @@
+# Comment/uncomment the following line to disable/enable debugging
+#DEBUG = y
+
+# Add your debugging flag (or not) to CFLAGS
+ifeq ($(DEBUG),y)
+  DEBFLAGS = -O -g # "-O" is needed to expand inlines
+else
+  DEBFLAGS = -O2
+endif
+
+EXTRA_CFLAGS += $(DEBFLAGS) -I$(LDDINCDIR)
+
+ifneq ($(KERNELRELEASE),)
+# call from kernel build system
+
+obj-m  := tmem_test.o
+
+else
+
+KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+PWD       := $(shell pwd)
+
+default:
+       $(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINCDIR=$(PWD)/../include modules
+
+endif
+
+clean:
+       rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
+
+depend .depend dep:
+       $(CC) $(CFLAGS) -M *.c > .depend
+
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/root_image/drivers/tmem_test/tmem_test.c b/root_image/drivers/tmem_test/tmem_test.c
new file mode 100644 (file)
index 0000000..a162afd
--- /dev/null
@@ -0,0 +1,322 @@
+#define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <linux/pagemap.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <xen/xen.h>
+#include <xen/interface/xen.h>
+#include <xen/page.h>
+#include <asm/xen/hypercall.h>
+#include <asm/xen/hypervisor.h>
+#include <xen/tmem.h>
+
+
+#define TMEM_TEST  "0.1"
+
+MODULE_AUTHOR("Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>");
+MODULE_DESCRIPTION("tmem_test");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(TMEM_TEST);
+
+static bool shared __read_mostly = true;
+module_param(shared, bool, S_IRUGO);
+
+#define MAX_PAGES 20
+struct tmem_oid {
+       u64 oid[3];
+};
+struct tmem_pool_uuid {
+       u64 lo;
+       u64 hi;
+};
+struct _arg {
+       int flags;
+       int pool;
+       int rc;
+       struct tmem_oid oid;
+       struct tmem_pool_uuid uuid;
+};
+
+
+#define TMEM_CONTROL               0
+#define TMEM_NEW_POOL              1
+#define TMEM_DESTROY_POOL          2
+#define TMEM_NEW_PAGE              3
+#define TMEM_PUT_PAGE              4
+#define TMEM_GET_PAGE              5
+
+#define TMEM_FLUSH_PAGE            6
+#define TMEM_FLUSH_OBJECT          7
+#define TMEM_READ                  8
+#define TMEM_WRITE                 9
+#define TMEM_XCHG                 10
+
+/* Bits for HYPERVISOR_tmem_op(TMEM_NEW_POOL) */
+#define TMEM_POOL_PERSIST          1
+#define TMEM_POOL_SHARED           2
+#define TMEM_POOL_PAGESIZE_SHIFT   4
+#define TMEM_VERSION_SHIFT        24
+
+#define EFROZEN                        1000
+#define EEMPTY                 1001
+static inline int xen_tmem_op(u32 tmem_cmd, u32 tmem_pool, struct tmem_oid oid,
+       u32 index, unsigned long gmfn)
+{
+       struct tmem_op op;
+       int rc = 0;
+
+       op.cmd = tmem_cmd;
+       op.pool_id = tmem_pool;
+       op.u.gen.oid[0] = oid.oid[0];
+       op.u.gen.oid[1] = oid.oid[1];
+       op.u.gen.oid[2] = oid.oid[2];
+       op.u.gen.index = index;
+       op.u.gen.tmem_offset = 0;
+       op.u.gen.pfn_offset = 0;
+       op.u.gen.len = 0;
+       set_xen_guest_handle(op.u.gen.gmfn, (void *)gmfn);
+       rc = HYPERVISOR_tmem_op(&op);
+       return rc;
+}
+static int xen_tmem_new_pool(struct tmem_pool_uuid uuid, u32 flags, unsigned long pagesize)
+{
+       struct tmem_op op;
+       int rc = 0, pageshift;
+
+       for (pageshift = 0; pagesize != 1; pageshift++)
+               pagesize >>= 1;
+       flags |= (pageshift - 12) << TMEM_POOL_PAGESIZE_SHIFT;
+       flags |= TMEM_SPEC_VERSION << TMEM_VERSION_SHIFT;
+       op.cmd = TMEM_NEW_POOL;
+       op.u.new.uuid[0] = uuid.lo;
+       op.u.new.uuid[1] = uuid.hi;
+       op.u.new.flags = flags;
+       rc = HYPERVISOR_tmem_op(&op);
+       return rc;
+}
+
+/* xen generic tmem ops */
+
+static int xen_tmem_put_page(u32 pool_id, struct tmem_oid oid,
+                            u32 index, unsigned long pfn)
+{
+       unsigned long gmfn = xen_pv_domain() ? pfn_to_mfn(pfn) : pfn;
+
+       return xen_tmem_op(TMEM_PUT_PAGE, pool_id, oid, index, gmfn);
+}
+static int xen_tmem_get_page(u32 pool_id, struct tmem_oid oid,
+                            u32 index, unsigned long pfn)
+{
+       unsigned long gmfn = xen_pv_domain() ? pfn_to_mfn(pfn) : pfn;
+
+       return xen_tmem_op(TMEM_GET_PAGE, pool_id, oid, index, gmfn);
+}
+
+static int xen_tmem_destroy_pool(u32 pool_id)
+{
+       struct tmem_oid oid = { { 0 } };
+
+       return xen_tmem_op(TMEM_DESTROY_POOL, pool_id, oid, 0, 0);
+}
+
+static int thread(void *_arg)
+{
+       struct _arg *arg = (struct _arg *)_arg;
+       struct page *a[MAX_PAGES];
+       struct tmem_oid oid[MAX_PAGES];
+       unsigned int i, j;
+       int rc = 0;
+
+       if (!_arg) {
+               pr_warn("No arguments passed in thread!\n");
+               return -EINVAL;
+       }
+       pr_info("pool=%d, flags=%d, uuid=%lx:%lx\n", arg->pool, arg->flags,
+               (unsigned long)arg->uuid.lo, (unsigned long)arg->uuid.hi);
+       arg->rc = 0;
+       do {
+               for (j = 0, i = 0;i < MAX_PAGES; i++, j++) {
+                       a[i] = alloc_page(GFP_KERNEL);
+                       if (!a[i])
+                               break;
+               }
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout_interruptible(HZ);
+               for (i = 0; i < j; i++) {
+                       unsigned long *addr = page_address(a[i]);
+                       if (addr) {
+                               memset(addr, 0xc2, PAGE_SIZE);
+                       }
+                       oid[i].oid[0] = arg->oid.oid[0];
+                       oid[i].oid[1] = arg->oid.oid[1];
+                       oid[i].oid[2] = (u64)addr;
+               }
+again:
+               /* Do the tmem operation. */
+               for (i = 0; i < j; i++) {
+                       struct page *page = a[i];
+                       unsigned long pfn = page_to_pfn(page);
+
+                       rc = xen_tmem_put_page(arg->pool, oid[i], 0,  pfn);
+
+                       if (rc != 1) {
+                               pr_warn("pool=%d i=%d PUT PFN=0x%lx, rc=%d!\n", arg->pool,i, pfn, rc);
+                               if (rc == -EFROZEN || rc == -ENOMEM) {
+                                       set_current_state(TASK_INTERRUPTIBLE);
+                                       schedule_timeout_interruptible(HZ);
+                                       goto again;
+                               }
+                               arg->rc = rc;
+                               break;
+                       }
+               }
+               if (rc != 1)
+                       break;
+               rc = 0;
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout_interruptible(HZ);
+               for (i = 0; i < j; i++) {
+                       struct page *page = a[i];
+                       unsigned long pfn = page_to_pfn(page);
+                       unsigned long *addr = page_address(page);
+
+                       rc = xen_tmem_get_page(arg->pool, oid[i], 0,  pfn);
+
+                       if (rc != 1) {
+                               pr_warn("pool=%d i=%d GET PFN=0x%lx, rc=%d!\n", arg->pool, i, pfn, rc);
+                               arg->rc = rc;
+                               break;
+                       }
+                       if (addr) {
+                               unsigned long v;
+                               for (v = 0; v < PAGE_SIZE / sizeof(*addr); v += sizeof(*addr))
+                               {
+                                       if (addr[v] != 0xc2c2c2c2c2c2c2c2) {
+                                               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, addr, PAGE_SIZE);
+                                               pr_warn("pool=%d i=%d UUID=%lx:%lx failed! Have: [0x%lx]\n", arg->pool, i,
+                                                       (unsigned long)arg->uuid.lo, (unsigned long)arg->uuid.hi,
+                                                       addr[v]);
+                                               BUG();
+                                       }
+                               }
+                       }
+               }
+               if (rc != 1)
+                       break;
+               rc = 0;
+               for (i = 0; i< MAX_PAGES; i++) {
+                       if (a[i])
+                               __free_page(a[i]);
+                       a[i] = NULL;
+               }
+       } while (!kthread_should_stop());
+       return rc;
+}
+#define MAX_THREADS 4
+static struct task_struct *t[MAX_THREADS];
+static struct _arg a[MAX_THREADS];
+
+static int __init tmem_test_init(void)
+{
+       unsigned int i;
+       int rc;
+
+       /* First is TMEM_POOL_PERSIST */
+       i = 0;
+       a[i].uuid.lo = 0;
+       a[i].uuid.hi = 0;
+       a[i].flags = TMEM_POOL_PERSIST;
+       a[i].pool = -1;
+       a[i].oid.oid[0] = 0x1000+i;
+
+       if (shared) {
+               i++;
+               a[i].uuid.lo = 0xdeadbeef;
+               a[i].uuid.hi = 0;
+               a[i].flags = TMEM_POOL_SHARED;
+               a[i].pool = -1;
+               a[i].oid.oid[0] = 0x1000+i;
+
+               i++;
+               a[i].uuid.lo = 0xdeadbeef;
+               a[i].uuid.hi = 0;
+               a[i].flags = TMEM_POOL_SHARED;
+               a[i].pool = -1;
+               a[i].oid.oid[0] = 0x1000+i;
+       } else {
+               i++;
+               a[i].oid.oid[0] = 0;
+               a[i].pool = -1;
+               i++;
+               a[i].oid.oid[0] = 0;
+               a[i].pool = -1;
+       }
+       i++;
+       a[i].uuid.lo = 0xbad;
+       a[i].uuid.hi = 0xf00d;
+       a[i].flags = 0;
+       a[i].pool = -1;
+       a[i].oid.oid[0] = 0x1000+i;
+
+       for (i = 0; i < MAX_THREADS; i++) {
+               a[i].rc = 0;
+               if (!a[i].oid.oid[0])
+                       continue;
+
+               rc = xen_tmem_new_pool(a[i].uuid, a[i].flags, PAGE_SIZE);
+               if (rc < 0) {
+                       pr_warn("%d UUID=%lx:%lx flags=0x%x failed with rc=%d\n",
+                               i, (unsigned long)a[i].uuid.lo, (unsigned long)a[i].uuid.hi, a[i].flags, rc);
+                       rc = -EINVAL;
+                       goto exit;
+               }
+               a[i].pool = rc;
+       }
+       pr_info("Pools allocated.\n");
+       for (i = 0; i < MAX_THREADS; i++) {
+               if (!a[i].oid.oid[0])
+                       continue;
+               t[i] = kthread_run(thread, &a[i], "tmem_test");
+               if (!t[i]) {
+                       rc = -EINVAL;
+                       goto exit;
+               }
+       }
+
+       pr_info("Threads running.\n");
+       return 0;
+exit:
+       for (i = 0; i < MAX_THREADS; i++)
+       {
+               if (!a[i].oid.oid[0])
+                       continue;
+               if (t[i])
+                       kthread_stop(t[i]);
+       }
+       /* Two of the pools are shared so we need to stop workers first.*/
+       for (i = 0; i < MAX_THREADS; i++)
+               if (a[i].pool != -1)
+                       xen_tmem_destroy_pool(a[i].pool);
+       return rc;
+}
+static void __exit tmem_test_exit(void)
+{
+       unsigned int i;
+
+       for (i = 0; i < MAX_THREADS; i++) {
+               if (!a[i].oid.oid[0])
+                       continue;
+               if (t[i] && a[i].rc == 0)
+                               kthread_stop(t[i]);
+       }
+
+       for (i = 0; i < MAX_THREADS; i++) {
+               if (a[i].pool != -1)
+                       xen_tmem_destroy_pool(a[i].pool);
+       }
+}
+module_init(tmem_test_init);
+module_exit(tmem_test_exit);
index df6eff4ddf0f7bb48d748dd06b7fe9371725c111..c1490c424b01c3f95f1c5b3242d8d8dd5f03b665 100755 (executable)
@@ -145,8 +145,8 @@ if [ $? == 0 ]; then
                crashme)
                        while (true); do crashme +2000 666 100 1:00:00; echo "testing.."; done &
                        ;;
-               eatmem)
-                       while (true); do eatmem 64MB 10; echo "testing ..";done &
+               tmem)
+                       /etc/init.d/tmem
                        ;;
                dfb)
                        while (true); do dfbtest_fillrect; done &
diff --git a/root_image/etc/init.d/tmem b/root_image/etc/init.d/tmem
new file mode 100755 (executable)
index 0000000..1b6e9c1
--- /dev/null
@@ -0,0 +1,109 @@
+#!/bin/bash
+
+ . /etc/init.d/functions
+
+SWAP_SIZE="+768M"
+FS_SIZE="+256M"
+FIO_TEST="/tmp/read.fio"
+
+tmem_check()
+{
+       local _rc=$1
+       if [ $_rc -ne 0 ]; then
+               echo "Failed with $_rc"
+               exit $rc
+       fi
+}
+tmem_setup ()
+{
+       local disk=$1
+       echo "Erasing $disk"
+
+       (echo o; echo w) | fdisk $disk
+       rc=$?
+       tmem_check $rc
+       echo "-----------------------------------"
+       echo "Creating swap fs with $SWAP_SIZE"
+       (echo n; echo p;echo 1; echo 1; echo $SWAP_SIZE; echo w) | fdisk $disk
+       rc=$?
+       tmem_check $rc
+       echo "-----------------------------------"
+       echo "Creating fs partition"
+       echo -e "n\np\n2\n\n\nw" | fdisk $disk
+       #(echo n; echo p; echo 2; echo 1; echo $FS_SIZE; echo w) | fdisk $disk
+       rc=$?
+       tmem_check $rc
+
+       sync
+       sleep 5
+       echo "-----------------------------------"
+       echo "Formating swap partition"
+
+       mkswap ${disk}1
+       rc=$?
+       tmem_check $rc
+
+       echo "-----------------------------------"
+       echo "Formating FS partition"
+       mkfs.ext3 ${disk}2
+       rc=$?
+       tmem_check $rc
+
+       echo "sync"
+
+       sync
+
+
+       mkdir /TEST
+       mount ${disk}2 /TEST
+       rc=$?
+       tmem_check $rc
+
+       swapon ${disk}1
+       rc=$?
+       tmem_check $rc
+
+       return 0;
+}
+
+tmem_missing()
+{
+       echo "Missing binaries. Disabling tmem tests."
+       exit 1;
+}
+
+which mkswap 1>/dev/null 2>/dev/null
+if [ $? -eq 1 ]; then
+       tmem_missing
+fi
+which swapon 1>/dev/null 2>/dev/null
+if [ $? -eq 1 ]; then
+       tmem_missing
+fi
+
+# This should be figured by some boot parameters, but for now just assume
+# xvda
+tmem_setup /dev/xvda
+rc=$?
+if [ $rc -ne 0 ]; then
+       echo "Test failed with $rc!"
+       exit $rc
+fi
+modprobe tmem
+# Now the kernel will start pushing pages in swap..
+echo "Kicking off eatmem."
+
+echo "while (true); do  eatmem 100M 10; echo '+'; done" > /tmp/tmem.sh
+
+echo "[/TEST/test]" > $FIO_TEST
+echo "buffered=1" >> $FIO_TEST
+echo "rw=read" >> $FIO_TEST
+echo "runtime=360" >> $FIO_TEST
+echo "size=250M" >> $FIO_TEST
+echo "directory=/TEST" >> $FIO_TEST
+
+chmod 755 /tmp/tmem.sh
+nohup bash /tmp/tmem.sh  &
+nohup bash fio $FIO_TEST &
+
+modprobe tmem-test