diff options
Diffstat (limited to 'patches/boot_time_opt/0121-do-accept-in-LIFO-order-for-cache-efficiency.patch')
-rw-r--r-- | patches/boot_time_opt/0121-do-accept-in-LIFO-order-for-cache-efficiency.patch | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/patches/boot_time_opt/0121-do-accept-in-LIFO-order-for-cache-efficiency.patch b/patches/boot_time_opt/0121-do-accept-in-LIFO-order-for-cache-efficiency.patch new file mode 100644 index 0000000..23cbbb8 --- /dev/null +++ b/patches/boot_time_opt/0121-do-accept-in-LIFO-order-for-cache-efficiency.patch | |||
@@ -0,0 +1,89 @@ | |||
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
2 | From: Arjan van de Ven <arjan@linux.intel.com> | ||
3 | Date: Thu, 13 Dec 2018 01:00:49 +0000 | ||
4 | Subject: [PATCH] do accept() in LIFO order for cache efficiency | ||
5 | |||
6 | --- | ||
7 | include/linux/wait.h | 2 ++ | ||
8 | kernel/sched/wait.c | 24 ++++++++++++++++++++++++ | ||
9 | net/ipv4/inet_connection_sock.c | 2 +- | ||
10 | 3 files changed, 27 insertions(+), 1 deletion(-) | ||
11 | |||
12 | diff --git a/include/linux/wait.h b/include/linux/wait.h | ||
13 | index 27fb99cfeb02..9a2c36d081bf 100644 | ||
14 | --- a/include/linux/wait.h | ||
15 | +++ b/include/linux/wait.h | ||
16 | @@ -164,6 +164,7 @@ static inline bool wq_has_sleeper(struct wait_queue_head *wq_head) | ||
17 | |||
18 | extern void add_wait_queue(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry); | ||
19 | extern void add_wait_queue_exclusive(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry); | ||
20 | +extern void add_wait_queue_exclusive_lifo(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry); | ||
21 | extern void remove_wait_queue(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry); | ||
22 | |||
23 | static inline void __add_wait_queue(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry) | ||
24 | @@ -1127,6 +1128,7 @@ do { \ | ||
25 | */ | ||
26 | void prepare_to_wait(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state); | ||
27 | void prepare_to_wait_exclusive(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state); | ||
28 | +void prepare_to_wait_exclusive_lifo(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state); | ||
29 | long prepare_to_wait_event(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state); | ||
30 | void finish_wait(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry); | ||
31 | long wait_woken(struct wait_queue_entry *wq_entry, unsigned mode, long timeout); | ||
32 | diff --git a/kernel/sched/wait.c b/kernel/sched/wait.c | ||
33 | index 01f5d3020589..6fb633f219c4 100644 | ||
34 | --- a/kernel/sched/wait.c | ||
35 | +++ b/kernel/sched/wait.c | ||
36 | @@ -37,6 +37,17 @@ void add_wait_queue_exclusive(struct wait_queue_head *wq_head, struct wait_queue | ||
37 | } | ||
38 | EXPORT_SYMBOL(add_wait_queue_exclusive); | ||
39 | |||
40 | +void add_wait_queue_exclusive_lifo(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry) | ||
41 | +{ | ||
42 | + unsigned long flags; | ||
43 | + | ||
44 | + wq_entry->flags |= WQ_FLAG_EXCLUSIVE; | ||
45 | + spin_lock_irqsave(&wq_head->lock, flags); | ||
46 | + __add_wait_queue(wq_head, wq_entry); | ||
47 | + spin_unlock_irqrestore(&wq_head->lock, flags); | ||
48 | +} | ||
49 | +EXPORT_SYMBOL(add_wait_queue_exclusive_lifo); | ||
50 | + | ||
51 | void remove_wait_queue(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry) | ||
52 | { | ||
53 | unsigned long flags; | ||
54 | @@ -263,6 +274,19 @@ prepare_to_wait_exclusive(struct wait_queue_head *wq_head, struct wait_queue_ent | ||
55 | } | ||
56 | EXPORT_SYMBOL(prepare_to_wait_exclusive); | ||
57 | |||
58 | +void prepare_to_wait_exclusive_lifo(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state) | ||
59 | +{ | ||
60 | + unsigned long flags; | ||
61 | + | ||
62 | + wq_entry->flags |= WQ_FLAG_EXCLUSIVE; | ||
63 | + spin_lock_irqsave(&wq_head->lock, flags); | ||
64 | + if (list_empty(&wq_entry->entry)) | ||
65 | + __add_wait_queue(wq_head, wq_entry); | ||
66 | + set_current_state(state); | ||
67 | + spin_unlock_irqrestore(&wq_head->lock, flags); | ||
68 | +} | ||
69 | +EXPORT_SYMBOL(prepare_to_wait_exclusive_lifo); | ||
70 | + | ||
71 | void init_wait_entry(struct wait_queue_entry *wq_entry, int flags) | ||
72 | { | ||
73 | wq_entry->flags = flags; | ||
74 | diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c | ||
75 | index 1dfa561e8f98..f362411fcc93 100644 | ||
76 | --- a/net/ipv4/inet_connection_sock.c | ||
77 | +++ b/net/ipv4/inet_connection_sock.c | ||
78 | @@ -433,7 +433,7 @@ static int inet_csk_wait_for_connect(struct sock *sk, long timeo) | ||
79 | * having to remove and re-insert us on the wait queue. | ||
80 | */ | ||
81 | for (;;) { | ||
82 | - prepare_to_wait_exclusive(sk_sleep(sk), &wait, | ||
83 | + prepare_to_wait_exclusive_lifo(sk_sleep(sk), &wait, | ||
84 | TASK_INTERRUPTIBLE); | ||
85 | release_sock(sk); | ||
86 | if (reqsk_queue_empty(&icsk->icsk_accept_queue)) | ||
87 | -- | ||
88 | https://clearlinux.org | ||
89 | |||