Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1370493 > unrolled thread
| Started by | Michal Hocko <mhocko@kernel.org> |
|---|---|
| First post | 2016-04-04 11:20 +0200 |
| Last post | 2016-04-07 09:40 +0200 |
| Articles | 4 — 3 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [PATCH 03/11] locking, rwsem: introduce basis for down_write_killable Michal Hocko <mhocko@kernel.org> - 2016-04-04 11:20 +0200
Re: [PATCH 03/11] locking, rwsem: introduce basis for down_write_killable Peter Zijlstra <peterz@infradead.org> - 2016-04-04 11:30 +0200
Re: [PATCH 03/11] locking, rwsem: introduce basis for down_write_killable Davidlohr Bueso <dave@stgolabs.net> - 2016-04-07 09:00 +0200
Re: [PATCH 03/11] locking, rwsem: introduce basis for down_write_killable Michal Hocko <mhocko@kernel.org> - 2016-04-07 09:40 +0200
| From | Michal Hocko <mhocko@kernel.org> |
|---|---|
| Date | 2016-04-04 11:20 +0200 |
| Subject | Re: [PATCH 03/11] locking, rwsem: introduce basis for down_write_killable |
| Message-ID | <rk8PV-S8-35@gated-at.bofh.it> |
On Fri 01-04-16 21:41:25, Davidlohr Bueso wrote:
> On Fri, 01 Apr 2016, Michal Hocko wrote:
>
> >From: Michal Hocko <mhocko@suse.com>
> >
> >Introduce a generic implementation necessary for down_write_killable.
> >This is a trivial extension of the already existing down_write call
> >which can be interrupted by SIGKILL. This patch doesn't provide
> >down_write_killable yet because arches have to provide the necessary
> >pieces before.
> >
> >rwsem_down_write_failed which is a generic slow path for the
> >write lock is extended to allow a task state and renamed to
> >__rwsem_down_write_failed_state. The return value is either a valid
> >semaphore pointer or ERR_PTR(-EINTR).
> >
> >rwsem_down_write_failed_killable is exported as a new way to wait for
> >the lock and be killable.
> >
> >For rwsem-spinlock implementation the current __down_write it updated
> >in a similar way as __rwsem_down_write_failed_state except it doesn't
> >need new exports just visible __down_write_killable.
> >
> >Architectures which are not using the generic rwsem implementation are
> >supposed to provide their __down_write_killable implementation and
> >use rwsem_down_write_failed_killable for the slow path.
>
> So in a nutshell, this is supposed to be the (writer) rwsem counterpart of
> mutex_lock_killable() and down_killable(), right?
Yes.
> [...]
>
> >--- a/kernel/locking/rwsem-xadd.c
> >+++ b/kernel/locking/rwsem-xadd.c
> >@@ -433,12 +433,13 @@ static inline bool rwsem_has_spinner(struct rw_semaphore *sem)
> >/*
> > * Wait until we successfully acquire the write lock
> > */
> >-__visible
> >-struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore *sem)
> >+static inline struct rw_semaphore *
> >+__rwsem_down_write_failed_state(struct rw_semaphore *sem, int state)
>
> fwiw I'm not a fan of the _state naming. While I understand why you chose it, I feel
> it does not really describe the purpose of the call itself. The state logic alone is
> really quite small and therefore should not govern the function name. Why not just apply
> kiss and label things _common, ie like mutexes do? This would also standardize names a
> bit.
I really do not care much about naming. So if _common sounds better I
can certainly rename.
>
> >{
> > long count;
> > bool waiting = true; /* any queued threads before us */
> > struct rwsem_waiter waiter;
> >+ struct rw_semaphore *ret = sem;
> >
> > /* undo write bias from down_write operation, stop active locking */
> > count = rwsem_atomic_update(-RWSEM_ACTIVE_WRITE_BIAS, sem);
> >@@ -478,7 +479,7 @@ struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore *sem)
> > count = rwsem_atomic_update(RWSEM_WAITING_BIAS, sem);
> >
> > /* wait until we successfully acquire the lock */
> >- set_current_state(TASK_UNINTERRUPTIBLE);
> >+ set_current_state(state);
> > while (true) {
> > if (rwsem_try_write_lock(count, sem))
> > break;
> >@@ -486,21 +487,39 @@ struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore *sem)
> >
> > /* Block until there are no active lockers. */
> > do {
> >+ if (signal_pending_state(state, current)) {
>
> ^^ unlikely()?
The generated code is identical after I've added unlikely. I haven't
tried more gcc versions (mine is 5.3.1) but is this worth it?
>
> >+ raw_spin_lock_irq(&sem->wait_lock);
>
> If the lock is highly contended + a bad workload for spin-on-owner, this could take a while :)
> Of course, this is a side effect of the wait until no active lockers optimization which avoids
> the wait_lock in the first place, so fortunately it somewhat mitigates the situation.
>
> >+ ret = ERR_PTR(-EINTR);
> >+ goto out;
> >+ }
> > schedule();
> >- set_current_state(TASK_UNINTERRUPTIBLE);
> >+ set_current_state(state);
> > } while ((count = sem->count) & RWSEM_ACTIVE_MASK);
> >
> > raw_spin_lock_irq(&sem->wait_lock);
> > }
> >+out:
> > __set_current_state(TASK_RUNNING);
> >-
>
> You certainly don't want this iff exiting due to TASK_KILLABLE situation.
Not sure I got your point here.
--
Michal Hocko
SUSE Labs
[toc] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2016-04-04 11:30 +0200 |
| Message-ID | <rk8ZA-Wy-11@gated-at.bofh.it> |
| In reply to | #1370493 |
On Mon, Apr 04, 2016 at 11:17:00AM +0200, Michal Hocko wrote:
> > >@@ -486,21 +487,39 @@ struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore *sem)
> > >
> > > /* Block until there are no active lockers. */
> > > do {
> > >+ if (signal_pending_state(state, current)) {
> >
> > ^^ unlikely()?
>
> The generated code is identical after I've added unlikely. I haven't
> tried more gcc versions (mine is 5.3.1) but is this worth it?
Both signal_pending() and __fatal_signal_pending() already have an
unlikely(), which is why adding it here is superfluous.
[toc] | [prev] | [next] | [standalone]
| From | Davidlohr Bueso <dave@stgolabs.net> |
|---|---|
| Date | 2016-04-07 09:00 +0200 |
| Message-ID | <rlc53-8lR-7@gated-at.bofh.it> |
| In reply to | #1370493 |
On Mon, 04 Apr 2016, Michal Hocko wrote: >Not sure I got your point here. You set current to TASK_KILLABLE in the sleep loop, why do you want to change it here to TASK_RUNNING if its about to be killed? At least in the case of UNINTERRUPTABLE we do it merely as a redundancy after the breaking out of the loop. Of course we also acquired the lock in the first place by that time and we _better_ be running. Thanks, Davidlohr
[toc] | [prev] | [next] | [standalone]
| From | Michal Hocko <mhocko@kernel.org> |
|---|---|
| Date | 2016-04-07 09:40 +0200 |
| Message-ID | <rlcHL-pI-7@gated-at.bofh.it> |
| In reply to | #1373111 |
On Wed 06-04-16 23:58:07, Davidlohr Bueso wrote: > On Mon, 04 Apr 2016, Michal Hocko wrote: > > >Not sure I got your point here. > > You set current to TASK_KILLABLE in the sleep loop, why do you want to change > it here to TASK_RUNNING if its about to be killed? Wouldn't it be unexpected to return from a lock with something else than TASK_RUNNING? > At least in the case of > UNINTERRUPTABLE we do it merely as a redundancy after the breaking out of the > loop. Of course we also acquired the lock in the first place by that time and > we _better_ be running. I guess the reason was that rwsem_try_write_lock might suceed and we do not want to return with TASK_UNINTERRUPTIBLE in that case. -- Michal Hocko SUSE Labs
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web