summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/nvdimm/Kbuild11
-rw-r--r--tools/testing/nvdimm/config_check.c2
-rw-r--r--tools/testing/nvdimm/test/iomap.c27
-rw-r--r--tools/testing/nvdimm/test/nfit.c90
-rwxr-xr-xtools/testing/selftests/ftrace/ftracetest9
-rw-r--r--tools/testing/selftests/ftrace/test.d/event/event-pid.tc72
-rw-r--r--tools/testing/selftests/ftrace/test.d/instances/instance-event.tc138
-rwxr-xr-xtools/testing/selftests/intel_pstate/run.sh2
-rw-r--r--tools/virtio/ringtest/Makefile5
-rw-r--r--tools/virtio/ringtest/main.c2
-rw-r--r--tools/virtio/ringtest/virtio_ring_0_9.c49
-rw-r--r--tools/virtio/ringtest/virtio_ring_inorder.c2
12 files changed, 381 insertions, 28 deletions
diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild
index a34bfd0..7859856 100644
--- a/tools/testing/nvdimm/Kbuild
+++ b/tools/testing/nvdimm/Kbuild
@@ -7,6 +7,7 @@ ldflags-y += --wrap=ioremap_nocache
ldflags-y += --wrap=iounmap
ldflags-y += --wrap=memunmap
ldflags-y += --wrap=__devm_request_region
+ldflags-y += --wrap=__devm_release_region
ldflags-y += --wrap=__request_region
ldflags-y += --wrap=__release_region
ldflags-y += --wrap=devm_memremap_pages
@@ -15,6 +16,7 @@ ldflags-y += --wrap=phys_to_pfn_t
DRIVERS := ../../../drivers
NVDIMM_SRC := $(DRIVERS)/nvdimm
ACPI_SRC := $(DRIVERS)/acpi
+DAX_SRC := $(DRIVERS)/dax
obj-$(CONFIG_LIBNVDIMM) += libnvdimm.o
obj-$(CONFIG_BLK_DEV_PMEM) += nd_pmem.o
@@ -22,6 +24,8 @@ obj-$(CONFIG_ND_BTT) += nd_btt.o
obj-$(CONFIG_ND_BLK) += nd_blk.o
obj-$(CONFIG_X86_PMEM_LEGACY) += nd_e820.o
obj-$(CONFIG_ACPI_NFIT) += nfit.o
+obj-$(CONFIG_DEV_DAX) += dax.o
+obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o
nfit-y := $(ACPI_SRC)/nfit.o
nfit-y += config_check.o
@@ -38,6 +42,12 @@ nd_blk-y += config_check.o
nd_e820-y := $(NVDIMM_SRC)/e820.o
nd_e820-y += config_check.o
+dax-y := $(DAX_SRC)/dax.o
+dax-y += config_check.o
+
+dax_pmem-y := $(DAX_SRC)/pmem.o
+dax_pmem-y += config_check.o
+
libnvdimm-y := $(NVDIMM_SRC)/core.o
libnvdimm-y += $(NVDIMM_SRC)/bus.o
libnvdimm-y += $(NVDIMM_SRC)/dimm_devs.o
@@ -49,6 +59,7 @@ libnvdimm-y += $(NVDIMM_SRC)/label.o
libnvdimm-$(CONFIG_ND_CLAIM) += $(NVDIMM_SRC)/claim.o
libnvdimm-$(CONFIG_BTT) += $(NVDIMM_SRC)/btt_devs.o
libnvdimm-$(CONFIG_NVDIMM_PFN) += $(NVDIMM_SRC)/pfn_devs.o
+libnvdimm-$(CONFIG_NVDIMM_DAX) += $(NVDIMM_SRC)/dax_devs.o
libnvdimm-y += config_check.o
obj-m += test/
diff --git a/tools/testing/nvdimm/config_check.c b/tools/testing/nvdimm/config_check.c
index f2c7615..adf18bf 100644
--- a/tools/testing/nvdimm/config_check.c
+++ b/tools/testing/nvdimm/config_check.c
@@ -12,4 +12,6 @@ void check(void)
BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_BTT));
BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_BLK));
BUILD_BUG_ON(!IS_MODULE(CONFIG_ACPI_NFIT));
+ BUILD_BUG_ON(!IS_MODULE(CONFIG_DEV_DAX));
+ BUILD_BUG_ON(!IS_MODULE(CONFIG_DEV_DAX_PMEM));
}
diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c
index 0c1a7e6..c842095 100644
--- a/tools/testing/nvdimm/test/iomap.c
+++ b/tools/testing/nvdimm/test/iomap.c
@@ -239,13 +239,11 @@ struct resource *__wrap___devm_request_region(struct device *dev,
}
EXPORT_SYMBOL(__wrap___devm_request_region);
-void __wrap___release_region(struct resource *parent, resource_size_t start,
- resource_size_t n)
+static bool nfit_test_release_region(struct resource *parent,
+ resource_size_t start, resource_size_t n)
{
- struct nfit_test_resource *nfit_res;
-
if (parent == &iomem_resource) {
- nfit_res = get_nfit_res(start);
+ struct nfit_test_resource *nfit_res = get_nfit_res(start);
if (nfit_res) {
struct resource *res = nfit_res->res + 1;
@@ -254,11 +252,26 @@ void __wrap___release_region(struct resource *parent, resource_size_t start,
__func__, start, n, res);
else
memset(res, 0, sizeof(*res));
- return;
+ return true;
}
}
- __release_region(parent, start, n);
+ return false;
+}
+
+void __wrap___release_region(struct resource *parent, resource_size_t start,
+ resource_size_t n)
+{
+ if (!nfit_test_release_region(parent, start, n))
+ __release_region(parent, start, n);
}
EXPORT_SYMBOL(__wrap___release_region);
+void __wrap___devm_release_region(struct device *dev, struct resource *parent,
+ resource_size_t start, resource_size_t n)
+{
+ if (!nfit_test_release_region(parent, start, n))
+ __devm_release_region(dev, parent, start, n);
+}
+EXPORT_SYMBOL(__wrap___devm_release_region);
+
MODULE_LICENSE("GPL v2");
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index 3187322..c919866 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -330,12 +330,49 @@ static int nfit_test_cmd_clear_error(struct nd_cmd_clear_error *clear_err,
return 0;
}
+static int nfit_test_cmd_smart(struct nd_cmd_smart *smart, unsigned int buf_len)
+{
+ static const struct nd_smart_payload smart_data = {
+ .flags = ND_SMART_HEALTH_VALID | ND_SMART_TEMP_VALID
+ | ND_SMART_SPARES_VALID | ND_SMART_ALARM_VALID
+ | ND_SMART_USED_VALID | ND_SMART_SHUTDOWN_VALID,
+ .health = ND_SMART_NON_CRITICAL_HEALTH,
+ .temperature = 23 * 16,
+ .spares = 75,
+ .alarm_flags = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
+ .life_used = 5,
+ .shutdown_state = 0,
+ .vendor_size = 0,
+ };
+
+ if (buf_len < sizeof(*smart))
+ return -EINVAL;
+ memcpy(smart->data, &smart_data, sizeof(smart_data));
+ return 0;
+}
+
+static int nfit_test_cmd_smart_threshold(struct nd_cmd_smart_threshold *smart_t,
+ unsigned int buf_len)
+{
+ static const struct nd_smart_threshold_payload smart_t_data = {
+ .alarm_control = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
+ .temperature = 40 * 16,
+ .spares = 5,
+ };
+
+ if (buf_len < sizeof(*smart_t))
+ return -EINVAL;
+ memcpy(smart_t->data, &smart_t_data, sizeof(smart_t_data));
+ return 0;
+}
+
static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
struct nvdimm *nvdimm, unsigned int cmd, void *buf,
unsigned int buf_len, int *cmd_rc)
{
struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
struct nfit_test *t = container_of(acpi_desc, typeof(*t), acpi_desc);
+ unsigned int func = cmd;
int i, rc = 0, __cmd_rc;
if (!cmd_rc)
@@ -344,8 +381,23 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
if (nvdimm) {
struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
+ unsigned long cmd_mask = nvdimm_cmd_mask(nvdimm);
- if (!nfit_mem || !test_bit(cmd, &nfit_mem->dsm_mask))
+ if (!nfit_mem)
+ return -ENOTTY;
+
+ if (cmd == ND_CMD_CALL) {
+ struct nd_cmd_pkg *call_pkg = buf;
+
+ buf_len = call_pkg->nd_size_in + call_pkg->nd_size_out;
+ buf = (void *) call_pkg->nd_payload;
+ func = call_pkg->nd_command;
+ if (call_pkg->nd_family != nfit_mem->family)
+ return -ENOTTY;
+ }
+
+ if (!test_bit(cmd, &cmd_mask)
+ || !test_bit(func, &nfit_mem->dsm_mask))
return -ENOTTY;
/* lookup label space for the given dimm */
@@ -356,7 +408,7 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
if (i >= ARRAY_SIZE(handle))
return -ENXIO;
- switch (cmd) {
+ switch (func) {
case ND_CMD_GET_CONFIG_SIZE:
rc = nfit_test_cmd_get_config_size(buf, buf_len);
break;
@@ -368,16 +420,22 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
rc = nfit_test_cmd_set_config_data(buf, buf_len,
t->label[i]);
break;
+ case ND_CMD_SMART:
+ rc = nfit_test_cmd_smart(buf, buf_len);
+ break;
+ case ND_CMD_SMART_THRESHOLD:
+ rc = nfit_test_cmd_smart_threshold(buf, buf_len);
+ break;
default:
return -ENOTTY;
}
} else {
struct ars_state *ars_state = &t->ars_state;
- if (!nd_desc || !test_bit(cmd, &nd_desc->dsm_mask))
+ if (!nd_desc || !test_bit(cmd, &nd_desc->cmd_mask))
return -ENOTTY;
- switch (cmd) {
+ switch (func) {
case ND_CMD_ARS_CAP:
rc = nfit_test_cmd_ars_cap(buf, buf_len);
break;
@@ -1251,13 +1309,15 @@ static void nfit_test0_setup(struct nfit_test *t)
post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA0_SIZE);
acpi_desc = &t->acpi_desc;
- set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_dsm_force_en);
- set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en);
- set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en);
- set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_dsm_force_en);
- set_bit(ND_CMD_ARS_START, &acpi_desc->bus_dsm_force_en);
- set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_dsm_force_en);
- set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_dsm_force_en);
+ set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_CMD_SMART, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_cmd_force_en);
+ set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en);
+ set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en);
+ set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en);
+ set_bit(ND_CMD_SMART_THRESHOLD, &acpi_desc->dimm_cmd_force_en);
}
static void nfit_test1_setup(struct nfit_test *t)
@@ -1315,10 +1375,10 @@ static void nfit_test1_setup(struct nfit_test *t)
post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA2_SIZE);
acpi_desc = &t->acpi_desc;
- set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_dsm_force_en);
- set_bit(ND_CMD_ARS_START, &acpi_desc->bus_dsm_force_en);
- set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_dsm_force_en);
- set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_dsm_force_en);
+ set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_cmd_force_en);
+ set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en);
+ set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en);
+ set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en);
}
static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa,
diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest
index da48812..4c6a0bf 100755
--- a/tools/testing/selftests/ftrace/ftracetest
+++ b/tools/testing/selftests/ftrace/ftracetest
@@ -88,7 +88,12 @@ parse_opts() { # opts
# Parameters
DEBUGFS_DIR=`grep debugfs /proc/mounts | cut -f2 -d' ' | head -1`
-TRACING_DIR=$DEBUGFS_DIR/tracing
+if [ -z "$DEBUGFS_DIR" ]; then
+ TRACING_DIR=`grep tracefs /proc/mounts | cut -f2 -d' ' | head -1`
+else
+ TRACING_DIR=$DEBUGFS_DIR/tracing
+fi
+
TOP_DIR=`absdir $0`
TEST_DIR=$TOP_DIR/test.d
TEST_CASES=`find_testcases $TEST_DIR`
@@ -102,7 +107,7 @@ parse_opts $*
[ $DEBUG -ne 0 ] && set -x
# Verify parameters
-if [ -z "$DEBUGFS_DIR" -o ! -d "$TRACING_DIR" ]; then
+if [ -z "$TRACING_DIR" -o ! -d "$TRACING_DIR" ]; then
errexit "No ftrace directory found"
fi
diff --git a/tools/testing/selftests/ftrace/test.d/event/event-pid.tc b/tools/testing/selftests/ftrace/test.d/event/event-pid.tc
new file mode 100644
index 0000000..d4ab27b
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/event/event-pid.tc
@@ -0,0 +1,72 @@
+#!/bin/sh
+# description: event tracing - restricts events based on pid
+
+do_reset() {
+ echo > set_event
+ echo > set_event_pid
+ echo 0 > options/event-fork
+ clear_trace
+}
+
+fail() { #msg
+ do_reset
+ echo $1
+ exit $FAIL
+}
+
+yield() {
+ ping localhost -c 1 || sleep .001 || usleep 1 || sleep 1
+}
+
+if [ ! -f set_event -o ! -d events/sched ]; then
+ echo "event tracing is not supported"
+ exit_unsupported
+fi
+
+if [ ! -f set_event_pid ]; then
+ echo "event pid filtering is not supported"
+ exit_unsupported
+fi
+
+reset_tracer
+do_reset
+
+echo 1 > events/sched/sched_switch/enable
+
+yield
+
+count=`cat trace | grep sched_switch | wc -l`
+if [ $count -eq 0 ]; then
+ fail "sched_switch events are not recorded"
+fi
+
+do_reset
+
+read mypid rest < /proc/self/stat
+
+echo $mypid > set_event_pid
+echo 'sched:sched_switch' > set_event
+
+yield
+
+count=`cat trace | grep sched_switch | grep -v "pid=$mypid" | wc -l`
+if [ $count -ne 0 ]; then
+ fail "sched_switch events from other task are recorded"
+fi
+
+do_reset
+
+echo $mypid > set_event_pid
+echo 1 > options/event-fork
+echo 1 > events/sched/sched_switch/enable
+
+yield
+
+count=`cat trace | grep sched_switch | grep -v "pid=$mypid" | wc -l`
+if [ $count -eq 0 ]; then
+ fail "sched_switch events from other task are not recorded"
+fi
+
+do_reset
+
+exit 0
diff --git a/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc b/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc
new file mode 100644
index 0000000..4c5a061
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc
@@ -0,0 +1,138 @@
+#!/bin/sh
+# description: Test creation and deletion of trace instances while setting an event
+
+if [ ! -d instances ] ; then
+ echo "no instance directory with this kernel"
+ exit_unsupported;
+fi
+
+fail() { # mesg
+ rmdir foo 2>/dev/null
+ echo $1
+ set -e
+ exit $FAIL
+}
+
+cd instances
+
+# we don't want to fail on error
+set +e
+
+mkdir x
+rmdir x
+result=$?
+
+if [ $result -ne 0 ]; then
+ echo "instance rmdir not supported"
+ exit_unsupported
+fi
+
+instance_slam() {
+ while :; do
+ mkdir foo 2> /dev/null
+ rmdir foo 2> /dev/null
+ done
+}
+
+instance_read() {
+ while :; do
+ cat foo/trace 1> /dev/null 2>&1
+ done
+}
+
+instance_set() {
+ while :; do
+ echo 1 > foo/events/sched/sched_switch
+ done 2> /dev/null
+}
+
+instance_slam &
+p1=$!
+echo $p1
+
+instance_set &
+p2=$!
+echo $p2
+
+instance_read &
+p3=$!
+echo $p3
+
+sleep 1
+
+kill -1 $p3
+kill -1 $p2
+kill -1 $p1
+
+echo "Wait for processes to finish"
+wait $p1 $p2 $p3
+echo "all processes finished, wait for cleanup"
+sleep 1
+
+mkdir foo
+ls foo > /dev/null
+rmdir foo
+if [ -d foo ]; then
+ fail "foo still exists"
+fi
+exit 0
+
+
+
+
+instance_slam() {
+ while :; do
+ mkdir x
+ mkdir y
+ mkdir z
+ rmdir x
+ rmdir y
+ rmdir z
+ done 2>/dev/null
+}
+
+instance_slam &
+p1=$!
+echo $p1
+
+instance_slam &
+p2=$!
+echo $p2
+
+instance_slam &
+p3=$!
+echo $p3
+
+instance_slam &
+p4=$!
+echo $p4
+
+instance_slam &
+p5=$!
+echo $p5
+
+ls -lR >/dev/null
+sleep 1
+
+kill -1 $p1
+kill -1 $p2
+kill -1 $p3
+kill -1 $p4
+kill -1 $p5
+
+echo "Wait for processes to finish"
+wait $p1 $p2 $p3 $p4 $p5
+echo "all processes finished, wait for cleanup"
+
+mkdir x y z
+ls x y z
+rmdir x y z
+for d in x y z; do
+ if [ -d $d ]; then
+ fail "instance $d still exists"
+ fi
+done
+
+set -e
+
+exit 0
diff --git a/tools/testing/selftests/intel_pstate/run.sh b/tools/testing/selftests/intel_pstate/run.sh
index bdaf37e..7868c10 100755
--- a/tools/testing/selftests/intel_pstate/run.sh
+++ b/tools/testing/selftests/intel_pstate/run.sh
@@ -32,7 +32,7 @@ EVALUATE_ONLY=0
max_cpus=$(($(nproc)-1))
# compile programs
-gcc -o aperf aperf.c -lm
+gcc aperf.c -Wall -D_GNU_SOURCE -o aperf -lm
[ $? -ne 0 ] && echo "Problem compiling aperf.c." && exit 1
gcc -o msr msr.c -lm
[ $? -ne 0 ] && echo "Problem compiling msr.c." && exit 1
diff --git a/tools/virtio/ringtest/Makefile b/tools/virtio/ringtest/Makefile
index feaa64a..6ba7455 100644
--- a/tools/virtio/ringtest/Makefile
+++ b/tools/virtio/ringtest/Makefile
@@ -1,6 +1,6 @@
all:
-all: ring virtio_ring_0_9 virtio_ring_poll
+all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder
CFLAGS += -Wall
CFLAGS += -pthread -O2 -ggdb
@@ -10,13 +10,16 @@ main.o: main.c main.h
ring.o: ring.c main.h
virtio_ring_0_9.o: virtio_ring_0_9.c main.h
virtio_ring_poll.o: virtio_ring_poll.c virtio_ring_0_9.c main.h
+virtio_ring_inorder.o: virtio_ring_inorder.c virtio_ring_0_9.c main.h
ring: ring.o main.o
virtio_ring_0_9: virtio_ring_0_9.o main.o
virtio_ring_poll: virtio_ring_poll.o main.o
+virtio_ring_inorder: virtio_ring_inorder.o main.o
clean:
-rm main.o
-rm ring.o ring
-rm virtio_ring_0_9.o virtio_ring_0_9
-rm virtio_ring_poll.o virtio_ring_poll
+ -rm virtio_ring_inorder.o virtio_ring_inorder
.PHONY: all clean
diff --git a/tools/virtio/ringtest/main.c b/tools/virtio/ringtest/main.c
index 3a5ff43..147abb4 100644
--- a/tools/virtio/ringtest/main.c
+++ b/tools/virtio/ringtest/main.c
@@ -115,7 +115,7 @@ static void run_guest(void)
do {
if (started < bufs &&
started - completed < max_outstanding) {
- r = add_inbuf(0, NULL, "Hello, world!");
+ r = add_inbuf(0, "Buffer\n", "Hello, world!");
if (__builtin_expect(r == 0, true)) {
++started;
if (!--tokick) {
diff --git a/tools/virtio/ringtest/virtio_ring_0_9.c b/tools/virtio/ringtest/virtio_ring_0_9.c
index 47c9a1a..7618662 100644
--- a/tools/virtio/ringtest/virtio_ring_0_9.c
+++ b/tools/virtio/ringtest/virtio_ring_0_9.c
@@ -26,6 +26,14 @@ struct vring ring;
* high bits of ring id ^ 0x8000).
*/
/* #ifdef RING_POLL */
+/* enabling the below activates experimental in-order code
+ * (which skips ring updates and reads and writes len in descriptor).
+ */
+/* #ifdef INORDER */
+
+#if defined(RING_POLL) && defined(INORDER)
+#error "RING_POLL and INORDER are mutually exclusive"
+#endif
/* how much padding is needed to avoid false cache sharing */
#define HOST_GUEST_PADDING 0x80
@@ -35,7 +43,11 @@ struct guest {
unsigned short last_used_idx;
unsigned short num_free;
unsigned short kicked_avail_idx;
+#ifndef INORDER
unsigned short free_head;
+#else
+ unsigned short reserved_free_head;
+#endif
unsigned char reserved[HOST_GUEST_PADDING - 10];
} guest;
@@ -66,8 +78,10 @@ void alloc_ring(void)
guest.avail_idx = 0;
guest.kicked_avail_idx = -1;
guest.last_used_idx = 0;
+#ifndef INORDER
/* Put everything in free lists. */
guest.free_head = 0;
+#endif
for (i = 0; i < ring_size - 1; i++)
ring.desc[i].next = i + 1;
host.used_idx = 0;
@@ -84,13 +98,20 @@ void alloc_ring(void)
/* guest side */
int add_inbuf(unsigned len, void *buf, void *datap)
{
- unsigned head, avail;
+ unsigned head;
+#ifndef INORDER
+ unsigned avail;
+#endif
struct vring_desc *desc;
if (!guest.num_free)
return -1;
+#ifdef INORDER
+ head = (ring_size - 1) & (guest.avail_idx++);
+#else
head = guest.free_head;
+#endif
guest.num_free--;
desc = ring.desc;
@@ -102,7 +123,9 @@ int add_inbuf(unsigned len, void *buf, void *datap)
* descriptors.
*/
desc[head].flags &= ~VRING_DESC_F_NEXT;
+#ifndef INORDER
guest.free_head = desc[head].next;
+#endif
data[head].data = datap;
@@ -113,8 +136,12 @@ int add_inbuf(unsigned len, void *buf, void *datap)
ring.avail->ring[avail & (ring_size - 1)] =
(head | (avail & ~(ring_size - 1))) ^ 0x8000;
#else
+#ifndef INORDER
+ /* Barrier A (for pairing) */
+ smp_release();
avail = (ring_size - 1) & (guest.avail_idx++);
ring.avail->ring[avail] = head;
+#endif
/* Barrier A (for pairing) */
smp_release();
#endif
@@ -141,15 +168,27 @@ void *get_buf(unsigned *lenp, void **bufp)
return NULL;
/* Barrier B (for pairing) */
smp_acquire();
+#ifdef INORDER
+ head = (ring_size - 1) & guest.last_used_idx;
+ index = head;
+#else
head = (ring_size - 1) & guest.last_used_idx;
index = ring.used->ring[head].id;
#endif
+
+#endif
+#ifdef INORDER
+ *lenp = ring.desc[index].len;
+#else
*lenp = ring.used->ring[head].len;
+#endif
datap = data[index].data;
*bufp = (void*)(unsigned long)ring.desc[index].addr;
data[index].data = NULL;
+#ifndef INORDER
ring.desc[index].next = guest.free_head;
guest.free_head = index;
+#endif
guest.num_free++;
guest.last_used_idx++;
return datap;
@@ -283,16 +322,24 @@ bool use_buf(unsigned *lenp, void **bufp)
smp_acquire();
used_idx &= ring_size - 1;
+#ifdef INORDER
+ head = used_idx;
+#else
head = ring.avail->ring[used_idx];
+#endif
desc = &ring.desc[head];
#endif
*lenp = desc->len;
*bufp = (void *)(unsigned long)desc->addr;
+#ifdef INORDER
+ desc->len = desc->len - 1;
+#else
/* now update used ring */
ring.used->ring[used_idx].id = head;
ring.used->ring[used_idx].len = desc->len - 1;
+#endif
/* Barrier B (for pairing) */
smp_release();
host.used_idx++;
diff --git a/tools/virtio/ringtest/virtio_ring_inorder.c b/tools/virtio/ringtest/virtio_ring_inorder.c
new file mode 100644
index 0000000..2438ca5
--- /dev/null
+++ b/tools/virtio/ringtest/virtio_ring_inorder.c
@@ -0,0 +1,2 @@
+#define INORDER 1
+#include "virtio_ring_0_9.c"
OpenPOWER on IntegriCloud