[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
Thu Jun 26 03:48:40 PDT 2014
n 06/25/2014 07:03 PM, Daniel Mack wrote:
> 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.
Thank you for your try.
> 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?
In fact, flush_kernel_vmap_range() is not common across all the architectures,
but a local function on some arch.
So I'm not sure I can create a generic fix for this hack at this moment.
-Takahiro AKASHI
>
> Thanks,
> Daniel
>
More information about the systemd-devel
mailing list