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

Daniel Mack daniel at zonque.org
Wed Jun 25 03:03:29 PDT 2014


On 06/25/2014 11:13 AM, AKASHI Takahiro wrote:
> 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

This seems to be ok. Later this week, I can test this on some old ARM
boards that reproducibly showed cache aliasing.

Could you make this a real, non-hackish patch please that just removes
the old implementation and uses flush_kernel_vmap_range() instead,
without the KDBUS_HACK conditionals?


Thanks,
Daniel


More information about the systemd-devel mailing list