diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-12-17 17:17:04 +0100 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-12-17 17:17:04 +0100 |
commit | 13c2d67776c968ea635fb4654df889bc14835363 (patch) | |
tree | ab3666ec3d062e27276ff849deda62345ce961d5 /debian | |
parent | 34f5046ec8833149c98d3fef530f8a5c4e85c0f4 (diff) |
add patch series
Diffstat (limited to 'debian')
4 files changed, 393 insertions, 0 deletions
diff --git a/debian/patches/0001-ipc-rework-the-kernel-message-buffer-cache.patch b/debian/patches/0001-ipc-rework-the-kernel-message-buffer-cache.patch new file mode 100644 index 0000000..b166cf0 --- /dev/null +++ b/debian/patches/0001-ipc-rework-the-kernel-message-buffer-cache.patch @@ -0,0 +1,325 @@ +From e23a941eaf5aabe087f50700213c05c6d269d63b Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Wed, 17 Dec 2014 14:21:15 +0100 +Subject: [PATCH gnumach 1/3] ipc: rework the kernel message buffer cache + +Keep a per-processor stack of free kernel messages buffers. + +* ipc/ipc_kmsg.h (IKM_CACHE_SIZE): New macro. +(struct ipc_mksg_cpu_cache): New type. +(ipc_kmsg_cache): Use the new type for the cache. +(ikm_cache): Drop macro. +(ikm_cache_get, ikm_cache_put): New functions. +(ikm_free): Return buffers instead of freeing them. +(_ikm_free): New version of `ikm_free' that only frees buffers. +* ipc/ipc_kmsg.c (ipc_kmsg_cache): Use new type. +(ipc_kmsg_get, ipc_kmsg_put): Use new functions. +* ipc/mach_msg.c (mach_msg_trap): Likewise. +* kern/exception.c (exception_raise): Likewise. +(exception_parse_reply): Likewise. +* kern/ipc_kobject.c (ipc_kobject_server): Likewise. +--- + ipc/ipc_kmsg.c | 29 ++++--------------- + ipc/ipc_kmsg.h | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- + ipc/mach_msg.c | 14 ++++----- + kern/exception.c | 28 ++++-------------- + kern/ipc_kobject.c | 6 +--- + 5 files changed, 97 insertions(+), 63 deletions(-) + +diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c +index 66643fd..04cdbc9 100644 +--- a/ipc/ipc_kmsg.c ++++ b/ipc/ipc_kmsg.c +@@ -73,7 +73,7 @@ + #define ptr_align(x) \ + ( ( ((vm_offset_t)(x)) + (sizeof(vm_offset_t)-1) ) & ~(sizeof(vm_offset_t)-1) ) + +-ipc_kmsg_t ipc_kmsg_cache[NCPUS]; ++struct ipc_kmsg_cpu_cache ipc_kmsg_cache[NCPUS]; + + /* + * Routine: ipc_kmsg_enqueue +@@ -506,23 +506,9 @@ ipc_kmsg_get( + if ((size < sizeof(mach_msg_header_t)) || (size & 3)) + return MACH_SEND_MSG_TOO_SMALL; + +- if (size <= IKM_SAVED_MSG_SIZE) { +- kmsg = ikm_cache(); +- if (kmsg != IKM_NULL) { +- ikm_cache() = IKM_NULL; +- ikm_check_initialized(kmsg, IKM_SAVED_KMSG_SIZE); +- } else { +- kmsg = ikm_alloc(IKM_SAVED_MSG_SIZE); +- if (kmsg == IKM_NULL) +- return MACH_SEND_NO_BUFFER; +- ikm_init(kmsg, IKM_SAVED_MSG_SIZE); +- } +- } else { +- kmsg = ikm_alloc(size); +- if (kmsg == IKM_NULL) +- return MACH_SEND_NO_BUFFER; +- ikm_init(kmsg, size); +- } ++ kmsg = ikm_cache_get (size); ++ if (kmsg == IKM_NULL) ++ return MACH_SEND_NO_BUFFER; + + if (copyinmsg(msg, &kmsg->ikm_header, size)) { + ikm_free(kmsg); +@@ -599,12 +585,7 @@ ipc_kmsg_put( + else + mr = MACH_MSG_SUCCESS; + +- if ((kmsg->ikm_size == IKM_SAVED_KMSG_SIZE) && +- (ikm_cache() == IKM_NULL)) +- ikm_cache() = kmsg; +- else +- ikm_free(kmsg); +- ++ ikm_cache_put (kmsg); + return mr; + } + +diff --git a/ipc/ipc_kmsg.h b/ipc/ipc_kmsg.h +index 620785b..c676996 100644 +--- a/ipc/ipc_kmsg.h ++++ b/ipc/ipc_kmsg.h +@@ -96,11 +96,36 @@ MACRO_END + * The per-processor cache seems to miss less than a per-thread cache, + * and it also uses less memory. Access to the cache doesn't + * require locking. ++ * ++ * The per-processor cache is a stack containing unused kernel ++ * message buffers. We choose IKM_CACHE_SIZE so that the size of ++ * the struct ipc_kmsg_cpu_cache is a multiple of a cache line, ++ * to prevent it bouncing between per-cpu caches. ++ * ++ * A kernel message buffer can be allocated using ++ * `ikm_cache_get', and returned using `ikm_cache_put'. + */ + +-extern ipc_kmsg_t ipc_kmsg_cache[NCPUS]; ++#define IKM_CACHE_SIZE (((1 << CPU_L1_SHIFT) - sizeof (size_t)) \ ++ / sizeof (ipc_kmsg_t)) ++ ++struct ipc_kmsg_cpu_cache ++{ ++ size_t count; ++ ipc_kmsg_t buffers[IKM_CACHE_SIZE]; ++}; ++ ++extern struct ipc_kmsg_cpu_cache ipc_kmsg_cache[NCPUS]; ++ ++/* Return a kernel message buffer of at least SIZE size, preferably ++ from the cache. This functions is defined below. */ ++static inline ipc_kmsg_t ikm_cache_get (mach_msg_size_t size) ++ __attribute__ ((always_inline)); + +-#define ikm_cache() ipc_kmsg_cache[cpu_number()] ++/* Return a kernel message buffer to the cache, or free it. This ++ functions is defined below. */ ++static inline void ikm_cache_put (ipc_kmsg_t kmsg) ++ __attribute__ ((always_inline)); + + /* + * The size of the kernel message buffers that will be cached. +@@ -150,11 +175,18 @@ MACRO_BEGIN \ + register vm_size_t _size = (kmsg)->ikm_size; \ + \ + if ((integer_t)_size > 0) \ +- kfree((vm_offset_t) (kmsg), _size); \ ++ ikm_cache_put (kmsg); \ + else \ + ipc_kmsg_free(kmsg); \ + MACRO_END + ++#define _ikm_free(kmsg) \ ++MACRO_BEGIN \ ++ vm_size_t _size = (kmsg)->ikm_size; \ ++ assert (_size != IKM_SIZE_NETWORK); \ ++ kfree((vm_offset_t) (kmsg), _size); \ ++MACRO_END ++ + /* + * struct ipc_kmsg_queue is defined in ipc/ipc_kmsg_queue.h + */ +@@ -280,5 +312,50 @@ ipc_kmsg_copyout_pseudo(ipc_kmsg_t, ipc_space_t, vm_map_t); + + extern void + ipc_kmsg_copyout_dest(ipc_kmsg_t, ipc_space_t); ++ ++static inline ipc_kmsg_t ++ikm_cache_get (mach_msg_size_t size) ++{ ++ ipc_kmsg_t kmsg; ++ struct ipc_kmsg_cpu_cache *c = &ipc_kmsg_cache[cpu_number ()]; ++ ++ if (size < IKM_SAVED_MSG_SIZE) ++ size = IKM_SAVED_MSG_SIZE; ++ ++ if (size > IKM_SAVED_MSG_SIZE ++ || c->count == 0) { ++ kmsg = ikm_alloc (size); ++ if (kmsg) ++ ikm_init (kmsg, size); ++ return kmsg; ++ } ++ ++ c->count -= 1; ++ kmsg = c->buffers[c->count]; ++ ++#if MACH_IPC_TEST ++ ikm_check_initialized (kmsg, IKM_SAVED_KMSG_SIZE); ++#endif /* MACH_IPC_TEST */ ++ return kmsg; ++} ++ ++static inline void ++ikm_cache_put (ipc_kmsg_t kmsg) ++{ ++ struct ipc_kmsg_cpu_cache *c = &ipc_kmsg_cache[cpu_number ()]; ++ ++ if (kmsg->ikm_size != IKM_SAVED_KMSG_SIZE ++ || c->count == IKM_CACHE_SIZE) { ++ _ikm_free (kmsg); ++ return; ++ } ++ ++ c->buffers[c->count] = kmsg; ++ c->count += 1; ++ ++#if MACH_IPC_TEST ++ ikm_check_initialized (kmsg, IKM_SAVED_KMSG_SIZE); ++#endif /* MACH_IPC_TEST */ ++} + + #endif /* _IPC_IPC_KMSG_H_ */ +diff --git a/ipc/mach_msg.c b/ipc/mach_msg.c +index 1e122c7..cdf16ea 100644 +--- a/ipc/mach_msg.c ++++ b/ipc/mach_msg.c +@@ -451,16 +451,14 @@ mach_msg_trap( + + if ((send_size > IKM_SAVED_MSG_SIZE) || + (send_size < sizeof(mach_msg_header_t)) || +- (send_size & 3) || +- ((kmsg = ikm_cache()) == IKM_NULL)) ++ (send_size & 3)) + goto slow_get; + +- ikm_cache() = IKM_NULL; +- ikm_check_initialized(kmsg, IKM_SAVED_KMSG_SIZE); ++ kmsg = ikm_cache_get (IKM_SAVED_MSG_SIZE); + + if (copyinmsg(msg, &kmsg->ikm_header, + send_size)) { +- ikm_free(kmsg); ++ ikm_cache_put (kmsg); + goto slow_get; + } + +@@ -1263,18 +1261,16 @@ mach_msg_trap( + * We have the reply message data in kmsg, + * and the reply message size in reply_size. + * Just need to copy it out to the user and free kmsg. +- * We must check ikm_cache after copyoutmsg. + */ + + ikm_check_initialized(kmsg, kmsg->ikm_size); + + if ((kmsg->ikm_size != IKM_SAVED_KMSG_SIZE) || + copyoutmsg(&kmsg->ikm_header, msg, +- reply_size) || +- (ikm_cache() != IKM_NULL)) ++ reply_size)) + goto slow_put; + +- ikm_cache() = kmsg; ++ ikm_cache_put (kmsg); + thread_syscall_return(MACH_MSG_SUCCESS); + /*NOTREACHED*/ + return MACH_MSG_SUCCESS; /* help for the compiler */ +diff --git a/kern/exception.c b/kern/exception.c +index 7954fba..72a4f29 100644 +--- a/kern/exception.c ++++ b/kern/exception.c +@@ -348,16 +348,9 @@ exception_raise( + * and it will give the buffer back with its reply. + */ + +- kmsg = ikm_cache(); +- if (kmsg != IKM_NULL) { +- ikm_cache() = IKM_NULL; +- ikm_check_initialized(kmsg, IKM_SAVED_KMSG_SIZE); +- } else { +- kmsg = ikm_alloc(IKM_SAVED_MSG_SIZE); +- if (kmsg == IKM_NULL) +- panic("exception_raise"); +- ikm_init(kmsg, IKM_SAVED_MSG_SIZE); +- } ++ kmsg = ikm_cache_get (IKM_SAVED_MSG_SIZE); ++ if (kmsg == IKM_NULL) ++ panic("exception_raise"); + + /* + * We need a reply port for the RPC. +@@ -681,22 +674,19 @@ exception_raise( + + /* + * Optimized version of ipc_kmsg_put. +- * We must check ikm_cache after copyoutmsg. + */ +- + ikm_check_initialized(kmsg, kmsg->ikm_size); + assert(kmsg->ikm_size == IKM_SAVED_KMSG_SIZE); + + if (copyoutmsg(&kmsg->ikm_header, receiver->ith_msg, +- sizeof(struct mach_exception)) || +- (ikm_cache() != IKM_NULL)) { ++ sizeof(struct mach_exception))) { + mr = ipc_kmsg_put(receiver->ith_msg, kmsg, + kmsg->ikm_header.msgh_size); + thread_syscall_return(mr); + /*NOTREACHED*/ + } + +- ikm_cache() = kmsg; ++ ikm_cache_put (kmsg); + thread_syscall_return(MACH_MSG_SUCCESS); + /*NOTREACHED*/ + #ifndef __GNUC__ +@@ -809,13 +799,7 @@ exception_parse_reply(ipc_kmsg_t kmsg) + } + + kr = msg->RetCode; +- +- if ((kmsg->ikm_size == IKM_SAVED_KMSG_SIZE) && +- (ikm_cache() == IKM_NULL)) +- ikm_cache() = kmsg; +- else +- ikm_free(kmsg); +- ++ ikm_cache_put (kmsg); + return kr; + } + +diff --git a/kern/ipc_kobject.c b/kern/ipc_kobject.c +index bf22028..27535b0 100644 +--- a/kern/ipc_kobject.c ++++ b/kern/ipc_kobject.c +@@ -236,11 +236,7 @@ ipc_kobject_server(request) + /* like ipc_kmsg_put, but without the copyout */ + + ikm_check_initialized(request, request->ikm_size); +- if ((request->ikm_size == IKM_SAVED_KMSG_SIZE) && +- (ikm_cache() == IKM_NULL)) +- ikm_cache() = request; +- else +- ikm_free(request); ++ ikm_cache_put (request); + } else { + /* + * The message contents of the request are intact. +-- +2.1.3 + diff --git a/debian/patches/0002-ipc-also-use-the-kernel-message-buffer-cache-for-ker.patch b/debian/patches/0002-ipc-also-use-the-kernel-message-buffer-cache-for-ker.patch new file mode 100644 index 0000000..aa64b34 --- /dev/null +++ b/debian/patches/0002-ipc-also-use-the-kernel-message-buffer-cache-for-ker.patch @@ -0,0 +1,40 @@ +From b4bfcd3564cd7443a44aa8f238c3c865a18a10f5 Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Wed, 17 Dec 2014 14:47:19 +0100 +Subject: [PATCH gnumach 2/3] ipc: also use the kernel message buffer cache for + kernel messages + +* ipc/ipc_kmsg.c (ipc_kmsg_get_from_kernel): Use the ikm cache. +(ipc_kmsg_put_to_kernel): Likewis. +--- + ipc/ipc_kmsg.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c +index 04cdbc9..c26569b 100644 +--- a/ipc/ipc_kmsg.c ++++ b/ipc/ipc_kmsg.c +@@ -544,10 +544,9 @@ ipc_kmsg_get_from_kernel( + assert(size >= sizeof(mach_msg_header_t)); + assert((size & 3) == 0); + +- kmsg = ikm_alloc(size); ++ kmsg = ikm_cache_get (size); + if (kmsg == IKM_NULL) + return MACH_SEND_NO_BUFFER; +- ikm_init(kmsg, size); + + memcpy(&kmsg->ikm_header, msg, size); + +@@ -611,7 +610,7 @@ ipc_kmsg_put_to_kernel( + + memcpy(msg, &kmsg->ikm_header, size); + +- ikm_free(kmsg); ++ ikm_cache_put (kmsg); + } + + /* +-- +2.1.3 + diff --git a/debian/patches/0003-doublesize-me.patch b/debian/patches/0003-doublesize-me.patch new file mode 100644 index 0000000..9e2c569 --- /dev/null +++ b/debian/patches/0003-doublesize-me.patch @@ -0,0 +1,25 @@ +From bcf91ed9f1877a8b1eaacf2bcb1e74c29e4110a3 Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Wed, 17 Dec 2014 16:50:29 +0100 +Subject: [PATCH gnumach 3/3] doublesize me + +--- + ipc/ipc_kmsg.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ipc/ipc_kmsg.h b/ipc/ipc_kmsg.h +index c676996..a2ac8ba 100644 +--- a/ipc/ipc_kmsg.h ++++ b/ipc/ipc_kmsg.h +@@ -106,7 +106,7 @@ MACRO_END + * `ikm_cache_get', and returned using `ikm_cache_put'. + */ + +-#define IKM_CACHE_SIZE (((1 << CPU_L1_SHIFT) - sizeof (size_t)) \ ++#define IKM_CACHE_SIZE ((4 * (1 << CPU_L1_SHIFT) - sizeof (size_t)) \ + / sizeof (ipc_kmsg_t)) + + struct ipc_kmsg_cpu_cache +-- +2.1.3 + diff --git a/debian/patches/series b/debian/patches/series index 52021c2..e318856 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -6,3 +6,6 @@ Add-some-padding-to-make-objects-fit-a-single-cache-.patch vm_cache_policy.patch +0001-ipc-rework-the-kernel-message-buffer-cache.patch +0002-ipc-also-use-the-kernel-message-buffer-cache-for-ker.patch +0003-doublesize-me.patch |