Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1485919 > unrolled thread
| Started by | Davidlohr Bueso <dave@stgolabs.net> |
|---|---|
| First post | 2016-09-18 21:20 +0200 |
| Last post | 2016-09-20 17:10 +0200 |
| Articles | 5 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH -next v2 0/5] ipc/sem: semop(2) improvements Davidlohr Bueso <dave@stgolabs.net> - 2016-09-18 21:20 +0200
[PATCH 5/5] ipc/sem: use proper list api for pending_list wakeups Davidlohr Bueso <dave@stgolabs.net> - 2016-09-18 21:20 +0200
[PATCH 4/5] ipc/sem: explicitly inline check_restart Davidlohr Bueso <dave@stgolabs.net> - 2016-09-18 21:20 +0200
Re: [PATCH -next v2 0/5] ipc/sem: semop(2) improvements Manfred Spraul <manfred@colorfullife.com> - 2016-09-19 20:50 +0200
Re: [PATCH -next v2 0/5] ipc/sem: semop(2) improvements Davidlohr Bueso <dave@stgolabs.net> - 2016-09-20 17:10 +0200
| From | Davidlohr Bueso <dave@stgolabs.net> |
|---|---|
| Date | 2016-09-18 21:20 +0200 |
| Subject | [PATCH -next v2 0/5] ipc/sem: semop(2) improvements |
| Message-ID | <siPN7-3Fd-3@gated-at.bofh.it> |
Changes from v1 (https://lkml.org/lkml/2016/9/12/266) - Got rid of the signal_pending check in wakeup fastpath. (patch 2) - Added read/access once to queue.status (we're obviously concerned about lockless access upon unrelated events, even if on the stack). - Got rid of initializing wake_q and wake_up_q call upon perform_atomic_semop error return path. (patch 2) - Documented ordering between wake_q_add and setting ->status. - What I did not do was refactor the checks in perfor_atomic_semop[_slow] as I could not get a decent/clean way of doing it without adding more unnecessary code. If we wanted to do smart semop scans that we received from userspace, this would still need to be done under sem_lock for semval values obviously. So I've left it as is, where we mainly duplicate the function, but I still believe this is the most straightforward way of dealing with this situation (patch 3). - Replaced using SEMOP_FAST with BITS_PER_LONG, as this is really what we want to limit the duplicate scanning. - More testing. - Added Manfred's ack (patch 5). Hi, Here are a few updates around the semop syscall handling that I noticed while reviewing Manfred's simple vs complex ops fixes. Changes are on top of -next, which means that Manfred's pending patches to ipc/sem.c that remove the redundant barrier(s) would probably have to be rebased. The patchset has survived the following testscases: - ltp - ipcsemtest (https://github.com/manfred-colorfu/ipcsemtest) - ipcscale (https://github.com/manfred-colorfu/ipcscale) Details are in each individual patch. Please consider for v4.9. Thanks! Davidlohr Bueso (5): ipc/sem: do not call wake_sem_queue_do() prematurely ipc/sem: rework task wakeups ipc/sem: optimize perform_atomic_semop() ipc/sem: explicitly inline check_restart ipc/sem: use proper list api for pending_list wakeups ipc/sem.c | 415 ++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 199 insertions(+), 216 deletions(-) -- 2.6.6
[toc] | [next] | [standalone]
| From | Davidlohr Bueso <dave@stgolabs.net> |
|---|---|
| Date | 2016-09-18 21:20 +0200 |
| Subject | [PATCH 5/5] ipc/sem: use proper list api for pending_list wakeups |
| Message-ID | <siPN8-3Fd-27@gated-at.bofh.it> |
| In reply to | #1485919 |
... saves some LoC and looks cleaner than re-implementing the
calls.
Acked-by: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
---
ipc/sem.c | 38 +++++++++++++-------------------------
1 file changed, 13 insertions(+), 25 deletions(-)
diff --git a/ipc/sem.c b/ipc/sem.c
index 89adba51e85f..e7da9821bf46 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -812,8 +812,7 @@ static inline int check_restart(struct sem_array *sma, struct sem_queue *q)
static int wake_const_ops(struct sem_array *sma, int semnum,
struct wake_q_head *wake_q)
{
- struct sem_queue *q;
- struct list_head *walk;
+ struct sem_queue *q, *tmp;
struct list_head *pending_list;
int semop_completed = 0;
@@ -822,25 +821,19 @@ static int wake_const_ops(struct sem_array *sma, int semnum,
else
pending_list = &sma->sem_base[semnum].pending_const;
- walk = pending_list->next;
- while (walk != pending_list) {
- int error;
-
- q = container_of(walk, struct sem_queue, list);
- walk = walk->next;
-
- error = perform_atomic_semop(sma, q);
-
- if (error <= 0) {
- /* operation completed, remove from queue & wakeup */
+ list_for_each_entry_safe(q, tmp, pending_list, list) {
+ int error = perform_atomic_semop(sma, q);
- unlink_queue(sma, q);
+ if (error > 0)
+ continue;
+ /* operation completed, remove from queue & wakeup */
+ unlink_queue(sma, q);
- wake_up_sem_queue_prepare(q, error, wake_q);
- if (error == 0)
- semop_completed = 1;
- }
+ wake_up_sem_queue_prepare(q, error, wake_q);
+ if (error == 0)
+ semop_completed = 1;
}
+
return semop_completed;
}
@@ -913,8 +906,7 @@ static int do_smart_wakeup_zero(struct sem_array *sma, struct sembuf *sops,
*/
static int update_queue(struct sem_array *sma, int semnum, struct wake_q_head *wake_q)
{
- struct sem_queue *q;
- struct list_head *walk;
+ struct sem_queue *q, *tmp;
struct list_head *pending_list;
int semop_completed = 0;
@@ -924,13 +916,9 @@ static int update_queue(struct sem_array *sma, int semnum, struct wake_q_head *w
pending_list = &sma->sem_base[semnum].pending_alter;
again:
- walk = pending_list->next;
- while (walk != pending_list) {
+ list_for_each_entry_safe(q, tmp, pending_list, list) {
int error, restart;
- q = container_of(walk, struct sem_queue, list);
- walk = walk->next;
-
/* If we are scanning the single sop, per-semaphore list of
* one semaphore and that semaphore is 0, then it is not
* necessary to scan further: simple increments
--
2.6.6
[toc] | [prev] | [next] | [standalone]
| From | Davidlohr Bueso <dave@stgolabs.net> |
|---|---|
| Date | 2016-09-18 21:20 +0200 |
| Subject | [PATCH 4/5] ipc/sem: explicitly inline check_restart |
| Message-ID | <siPN8-3Fd-31@gated-at.bofh.it> |
| In reply to | #1485919 |
The compiler already does this, but make it explicit. This helper
is really small and also used in update_queue's main loop, which is
O(N^2) scanning. Inline and avoid the function overhead.
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
---
ipc/sem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ipc/sem.c b/ipc/sem.c
index e868b5933ff8..89adba51e85f 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -771,7 +771,7 @@ static void unlink_queue(struct sem_array *sma, struct sem_queue *q)
* modified the array.
* Note that wait-for-zero operations are handled without restart.
*/
-static int check_restart(struct sem_array *sma, struct sem_queue *q)
+static inline int check_restart(struct sem_array *sma, struct sem_queue *q)
{
/* pending complex alter operations are too difficult to analyse */
if (!list_empty(&sma->pending_alter))
--
2.6.6
[toc] | [prev] | [next] | [standalone]
| From | Manfred Spraul <manfred@colorfullife.com> |
|---|---|
| Date | 2016-09-19 20:50 +0200 |
| Message-ID | <sjbNE-Bs-15@gated-at.bofh.it> |
| In reply to | #1485919 |
On 09/18/2016 09:11 PM, Davidlohr Bueso wrote:
> Changes from v1 (https://lkml.org/lkml/2016/9/12/266)
> - Got rid of the signal_pending check in wakeup fastpath. (patch 2)
> - Added read/access once to queue.status (we're obviously concerned about
> lockless access upon unrelated events, even if on the stack).
> - Got rid of initializing wake_q and wake_up_q call upon perform_atomic_semop
> error return path. (patch 2)
> - Documented ordering between wake_q_add and setting ->status.
> - What I did not do was refactor the checks in perfor_atomic_semop[_slow]
> as I could not get a decent/clean way of doing it without adding more
> unnecessary code. If we wanted to do smart semop scans that we received from
> userspace, this would still need to be done under sem_lock for semval values
> obviously. So I've left it as is, where we mainly duplicate the function, but
> I still believe this is the most straightforward way of dealing with this
> situation (patch 3).
> - Replaced using SEMOP_FAST with BITS_PER_LONG, as this is really what we want
> to limit the duplicate scanning.
> - More testing.
> - Added Manfred's ack (patch 5).
>
> Hi,
>
> Here are a few updates around the semop syscall handling that I noticed while
> reviewing Manfred's simple vs complex ops fixes. Changes are on top of -next,
> which means that Manfred's pending patches to ipc/sem.c that remove the redundant
> barrier(s) would probably have to be rebased.
>
> The patchset has survived the following testscases:
> - ltp
> - ipcsemtest (https://github.com/manfred-colorfu/ipcsemtest)
> - ipcscale (https://github.com/manfred-colorfu/ipcscale)
>
> Details are in each individual patch. Please consider for v4.9.
>
> Thanks!
>
> Davidlohr Bueso (5):
> ipc/sem: do not call wake_sem_queue_do() prematurely
The only patch that I don't like.
Especially: patch 2 of the series removes the wake_up_q from the
function epilogue.
So only the code duplication (additional instances of rcu_read_unlock())
remains, I don't see any advantages.
> ipc/sem: rework task wakeups
Acked
> ipc/sem: optimize perform_atomic_semop()
I'm still thinking about it.
Code duplication is evil, but perhaps it is the best solution.
What I don't like is the hardcoded "< BITS_PER_LONG".
At least:
- (1 << sop->sem_num)
+ (1 << (sop->sem_num%BITS_PER_LONG))
> ipc/sem: explicitly inline check_restart
Do we really need that? Isn't that the compiler's task?
Especially since the compiler is already doing it correctly.
> ipc/sem: use proper list api for pending_list wakeups
Acked
> ipc/sem.c | 415 ++++++++++++++++++++++++++++++--------------------------------
> 1 file changed, 199 insertions(+), 216 deletions(-)
>
--
Manfred
[toc] | [prev] | [next] | [standalone]
| From | Davidlohr Bueso <dave@stgolabs.net> |
|---|---|
| Date | 2016-09-20 17:10 +0200 |
| Message-ID | <sjuQi-4Gm-27@gated-at.bofh.it> |
| In reply to | #1486762 |
On Mon, 19 Sep 2016, Manfred Spraul wrote: >On 09/18/2016 09:11 PM, Davidlohr Bueso wrote: >>Davidlohr Bueso (5): >> ipc/sem: do not call wake_sem_queue_do() prematurely >The only patch that I don't like. >Especially: patch 2 of the series removes the wake_up_q from the >function epilogue. >So only the code duplication (additional instances of >rcu_read_unlock()) remains, I don't see any advantages. > >> ipc/sem: rework task wakeups >Acked Thanks. >> ipc/sem: optimize perform_atomic_semop() >I'm still thinking about it. >Code duplication is evil, but perhaps it is the best solution. > >What I don't like is the hardcoded "< BITS_PER_LONG". >At least: >- (1 << sop->sem_num) >+ (1 << (sop->sem_num%BITS_PER_LONG)) Yeah, I'll send v3 for that. >> ipc/sem: explicitly inline check_restart >Do we really need that? Isn't that the compiler's task? >Especially since the compiler is already doing it correctly. Yes, I mentioned in the changelog that the compiler does it and this is merely explicit. That said I see no harm in it, I guess whatever akpm says. >> ipc/sem: use proper list api for pending_list wakeups >Acked Thanks, Davidlohr
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web