Skip to content
This repository has been archived by the owner on Feb 26, 2020. It is now read-only.

SPL fixes #553

Closed
wants to merge 4 commits into from
Closed

SPL fixes #553

wants to merge 4 commits into from

Conversation

tuxoko
Copy link
Contributor

@tuxoko tuxoko commented May 21, 2016

  1. Restore CALLOUT_FLAG_ABSOLUTE in cv_timedwait_hires
  2. Fix splat-condvar on Linux 4.7
  3. Fix race in taskq_destroy and dynamic spawing

Chunwei Chen added 2 commits May 20, 2016 16:35
In 39cd90e, I mistakenly disabled the ability of using absolute expire time in
cv_timedwait_hires. I don't quite sure why I did that, so let's restore it.

Signed-off-by: Chunwei Chen <[email protected]>
Use schedule_timeout_interruptible instead of schedule for busy waiting.
Otherwise, it will cause "BUG: workqueue lockup" on Linux 4.7 pre-rc. This
should also reduce CPU usage in case we need to wait for a long time.

Signed-off-by: Chunwei Chen <[email protected]>
Fix openzfs#552
@dweeezil
Copy link
Contributor

Looking at the taskq_destroy/spawning issue only: I'm wondering whether you really need tqt_is_dynamic. It would seem that taskq_destroy could only do the wait-for-nspawn==0 loop if TASKQ_DYNAMIC were set. Similarly the taskq_thread could only decrement nspawn if TASKQ_DYNAMIC is set although it ought to be harmless to decrement it no matter what since nspawn should only be looked at for a TASKQ_DYNAMIC taskq.

@tuxoko
Copy link
Contributor Author

tuxoko commented May 21, 2016

Well, taskq_create will create one thread even if it's TASKQ_DYNAMIC.

@dweeezil
Copy link
Contributor

@tuxoko Interesting you should mention the single thread created for dynamic taskqs. There doesn't seem to be much of a need them to have a thread at all. What are your thoughts on 345f9be which changes things a few things in your patch? I've run the splat tests, ztest and a few hours (so far) of the test suite with it.

@tuxoko
Copy link
Contributor Author

tuxoko commented May 23, 2016

@dweeezil
Spawning one thread is probably and old relics before we spawn thread during taskq_dispatch.
I'm not sure about disable TASKQ_DYNAMIC when spl_taskq_thread_dynamic==0 though, we might want to be able to change that without reload the module. If you really dislike the tqt_is_dynamic, we can reset ns_spawn after wait_event(tq->tq_wait_waitq, tq->tq_nthreads == count);

@tuxoko
Copy link
Contributor Author

tuxoko commented May 23, 2016

@dweeezil
See if you like this one.
I also add another patch for taskq_wait_outstanding.

tq->tq_nspawn--;
spin_unlock_irqrestore(&tq->tq_lock, flags);
if (taskq_thread_create(tq) == NULL) {
/* restore spawning count if failed */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wondered at first the context of this comment (when looking at the original patch) and thought "restore to what"? How about:

/* cancel the request to spawn if thread creation fails */

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see how that makes it more understandable. The creation is already failed, and we are not actively cancel anything.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original comment was just fine once I thought about it for a moment.

@dweeezil
Copy link
Contributor

@tuxoko LGTM.

Chunwei Chen added 2 commits May 23, 2016 15:01
While taskq_destroy would wait for dynamic_taskq to finish its tasks, but it
does not implies the thread being spawned is up and running. This will cause
taskq to be freed before the thread can exit.

We fix this by using tq_nspawn to indicate how many threads are being spawned
before they are inserted to the thread list. And have taskq_destroy to wait
for it to drop to zero.

Signed-off-by: Chunwei Chen <[email protected]>
Fix openzfs#550
wait_event is a macro, so the current implementation will cause re-evaluation
of tq_next_id every time it wakes up. This would cause
taskq_wait_outstanding(tq, 0) to be equivalent to taskq_wait(tq)

Signed-off-by: Chunwei Chen <[email protected]>
/* get abs expire time */
tim += gethrtime();
if (!(flag & CALLOUT_FLAG_ABSOLUTE))
tim += gethrtime();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how I missed this when I looked over 39cd90e but yes we definitely need to restore this.

@behlendorf
Copy link
Contributor

@tuxoko these three LGTM.

e726590 Fix taskq_wait_outstanding re-evaluate tq_next_id
a815c53 Fix race between taskq_destroy and dynamic spawning thread
c1da2df Restore CALLOUT_FLAG_ABSOLUTE in cv_timedwait_hires

However, I'd like to hold off on this one until things settle down in the mainline kernel.

fc6269d Use schedule_timeout_interruptible for busy wait in splat-condvar.c

@tuxoko
Copy link
Contributor Author

tuxoko commented May 24, 2016

I'm fine with that.

behlendorf pushed a commit that referenced this pull request May 24, 2016
In 39cd90e, I mistakenly disabled the ability of using absolute expire time in
cv_timedwait_hires. I don't quite sure why I did that, so let's restore it.

Signed-off-by: Chunwei Chen <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Tim Chase <[email protected]>
Issue #553
behlendorf pushed a commit that referenced this pull request May 24, 2016
While taskq_destroy would wait for dynamic_taskq to finish its tasks, but it
does not implies the thread being spawned is up and running. This will cause
taskq to be freed before the thread can exit.

We fix this by using tq_nspawn to indicate how many threads are being spawned
before they are inserted to the thread list. And have taskq_destroy to wait
for it to drop to zero.

Signed-off-by: Chunwei Chen <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Tim Chase <[email protected]>
Issue #553
Closes #550
behlendorf pushed a commit that referenced this pull request May 24, 2016
wait_event is a macro, so the current implementation will cause re-
evaluation of tq_next_id every time it wakes up. This would cause
taskq_wait_outstanding(tq, 0) to be equivalent to taskq_wait(tq)

Signed-off-by: Chunwei Chen <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Tim Chase <[email protected]>
Issue #553
@behlendorf
Copy link
Contributor

Merged as:

b3a22a0 Fix taskq_wait_outstanding re-evaluate tq_next_id
5ce028b Fix race between taskq_destroy and dynamic spawning thread
872e0cc Restore CALLOUT_FLAG_ABSOLUTE in cv_timedwait_hires

@behlendorf behlendorf closed this May 24, 2016
tuxoko pushed a commit to tuxoko/spl that referenced this pull request Jun 14, 2016
wait_event is a macro, so the current implementation will cause re-
evaluation of tq_next_id every time it wakes up. This would cause
taskq_wait_outstanding(tq, 0) to be equivalent to taskq_wait(tq)

Signed-off-by: Chunwei Chen <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Tim Chase <[email protected]>
Issue openzfs#553
nedbass pushed a commit to nedbass/spl that referenced this pull request Aug 26, 2016
While taskq_destroy would wait for dynamic_taskq to finish its tasks, but it
does not implies the thread being spawned is up and running. This will cause
taskq to be freed before the thread can exit.

We fix this by using tq_nspawn to indicate how many threads are being spawned
before they are inserted to the thread list. And have taskq_destroy to wait
for it to drop to zero.

Signed-off-by: Chunwei Chen <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Tim Chase <[email protected]>
Issue openzfs#553
Closes openzfs#550
nedbass pushed a commit to nedbass/spl that referenced this pull request Aug 26, 2016
wait_event is a macro, so the current implementation will cause re-
evaluation of tq_next_id every time it wakes up. This would cause
taskq_wait_outstanding(tq, 0) to be equivalent to taskq_wait(tq)

Signed-off-by: Chunwei Chen <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Tim Chase <[email protected]>
Issue openzfs#553
tuxoko pushed a commit to tuxoko/spl that referenced this pull request Sep 8, 2016
While taskq_destroy would wait for dynamic_taskq to finish its tasks, but it
does not implies the thread being spawned is up and running. This will cause
taskq to be freed before the thread can exit.

We fix this by using tq_nspawn to indicate how many threads are being spawned
before they are inserted to the thread list. And have taskq_destroy to wait
for it to drop to zero.

Signed-off-by: Chunwei Chen <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Tim Chase <[email protected]>
Issue openzfs#553
Closes openzfs#550
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants