[systemd-devel] [RFC 7/8] HACK3: minimize the range of D-Cache flush in ioctl(CMD_MSG_RECV)

AKASHI Takahiro takahiro.akashi at linaro.org
Wed Jun 25 02:13:36 PDT 2014


Current ioctl(CMD_MSG_RECV) contains an expensive cache operation. Even if
the data is quite small, it always executes D-Cache flush on a buffer
at minimum unit of one page in kdbus_conn_msg_install() /
kdbus_pool_slice_flush() .
In fact, flush_dcache_page() implementation is very expensive on ARM since
flushing is repeated at every cache line in a page. This may not be seen on
x86 because it doesn't have ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE on.

This patch replaces flush_dcache_page() by flush_kernel_vmap_range() with
the exact offset and size of slice. (Actually aligned to a cache-line size).

Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
---
 pool.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/pool.c b/pool.c
index fcc54af..b723dd2 100644
--- a/pool.c
+++ b/pool.c
@@ -28,6 +28,13 @@
 #include "pool.h"
 #include "util.h"
 
+/*
+ * KDBUS_HACK3: Do dcache-flush only against the minimum range of slice
+ */
+#if KDBUS_HACK3
+#include <asm/cacheflush.h>
+#endif
+
 /**
  * struct kdbus_pool - the receiver's buffer
  * @f:			The backing shmem file
@@ -194,7 +201,13 @@ struct kdbus_pool_slice *kdbus_pool_slice_find(struct kdbus_pool *pool,
 int kdbus_pool_slice_alloc(struct kdbus_pool *pool,
 			   struct kdbus_pool_slice **slice, size_t size)
 {
+#if KDBUS_HACK3
+	/* FIXME: Assume that the cache line size is 128B. */
+#define DCACHE_ALIGN(size) ((size + 0x7f) & ~0x7fUL)
+	size_t slice_size = DCACHE_ALIGN(size);
+#else
 	size_t slice_size = KDBUS_ALIGN8(size);
+#endif
 	struct rb_node *n, *found = NULL;
 	struct kdbus_pool_slice *s;
 	int ret = 0;
@@ -620,6 +633,9 @@ exit_free:
  */
 void kdbus_pool_slice_flush(const struct kdbus_pool_slice *slice)
 {
+#if KDBUS_HACK3
+	flush_kernel_vmap_range((void *)slice->off, slice->size);
+#else
 #if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE == 1
 	struct address_space *mapping = slice->pool->f->f_mapping;
 	pgoff_t first = slice->off >> PAGE_CACHE_SHIFT;
@@ -638,6 +654,7 @@ void kdbus_pool_slice_flush(const struct kdbus_pool_slice *slice)
 		put_page(page);
 	}
 #endif
+#endif
 }
 
 /**
-- 
1.7.9.5



More information about the systemd-devel mailing list