Skip to content

Commit 206971d

Browse files
rtvdbehlendorf
authored andcommitted
OpenZFS 6739 - assumption in cv_timedwait_hires
Userland version of cv_timedwait_hires() always assumes absolute time. Reviewed by: Paul Dagnelie <[email protected]> Reviewed by: Matthew Ahrens <[email protected]> Reviewed by: Dan McDonald <[email protected]> Reviewed by: Robert Mustacchi <[email protected]> Approved by: Robert Mustacchi <[email protected]> Ported by: Denys Rtveliashvili <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> OpenZFS-issue: https://www.illumos.org/issues/6739 OpenZFS-commit: illumos/illumos-gate@41c6413 Porting Notes: The ported change has revealed a number of problems in the Linux-specific code, as it was expecting incorrect return codes from pthread_* functions. Reviewed and improved the usage of pthread_* function in lib/libzpool/kernel.c.
1 parent dabe1c4 commit 206971d

File tree

2 files changed

+26
-27
lines changed

2 files changed

+26
-27
lines changed

include/sys/zfs_context.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
/*
2626
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
2727
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
28-
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
28+
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
2929
*/
3030

3131
#ifndef _SYS_ZFS_CONTEXT_H
@@ -353,6 +353,7 @@ typedef struct kcondvar {
353353
} kcondvar_t;
354354

355355
#define CV_DEFAULT 0
356+
#define CALLOUT_FLAG_ABSOLUTE 0x2
356357

357358
extern void cv_init(kcondvar_t *cv, char *name, int type, void *arg);
358359
extern void cv_destroy(kcondvar_t *cv);

lib/libzpool/kernel.c

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,7 @@ thread_fini(void)
104104
kthread_nr--; /* Main thread is exiting */
105105

106106
while (kthread_nr > 0)
107-
VERIFY3S(pthread_cond_wait(&kthread_cond, &kthread_lock), ==,
108-
0);
107+
VERIFY0(pthread_cond_wait(&kthread_cond, &kthread_lock));
109108

110109
ASSERT3S(kthread_nr, ==, 0);
111110
VERIFY3S(pthread_mutex_unlock(&kthread_lock), ==, 0);
@@ -181,6 +180,10 @@ zk_thread_create(caddr_t stk, size_t stksize, thread_func_t func, void *arg,
181180

182181
VERIFY3S(stksize, >, 0);
183182
stksize = P2ROUNDUP(MAX(stksize, TS_STACK_MIN), PAGESIZE);
183+
/*
184+
* If this ever fails, it may be because the stack size is not a
185+
* multiple of system page size.
186+
*/
184187
VERIFY0(pthread_attr_setstacksize(&attr, stksize));
185188
VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE));
186189

@@ -199,11 +202,11 @@ zk_thread_exit(void)
199202

200203
umem_free(kt, sizeof (kthread_t));
201204

202-
pthread_mutex_lock(&kthread_lock);
205+
VERIFY0(pthread_mutex_lock(&kthread_lock));
203206
kthread_nr--;
204-
pthread_mutex_unlock(&kthread_lock);
207+
VERIFY0(pthread_mutex_unlock(&kthread_lock));
205208

206-
pthread_cond_broadcast(&kthread_cond);
209+
VERIFY0(pthread_cond_broadcast(&kthread_cond));
207210
pthread_exit((void *)TS_MAGIC);
208211
}
209212

@@ -316,13 +319,15 @@ mutex_enter(kmutex_t *mp)
316319
int
317320
mutex_tryenter(kmutex_t *mp)
318321
{
322+
int err;
319323
ASSERT3U(mp->m_magic, ==, MTX_MAGIC);
320324
ASSERT3P(mp->m_owner, !=, MTX_DEST);
321-
if (0 == pthread_mutex_trylock(&mp->m_lock)) {
325+
if (0 == (err = pthread_mutex_trylock(&mp->m_lock))) {
322326
ASSERT3P(mp->m_owner, ==, MTX_INIT);
323327
mp->m_owner = curthread;
324328
return (1);
325329
} else {
330+
VERIFY3S(err, ==, EBUSY);
326331
return (0);
327332
}
328333
}
@@ -464,14 +469,14 @@ cv_init(kcondvar_t *cv, char *name, int type, void *arg)
464469
{
465470
ASSERT3S(type, ==, CV_DEFAULT);
466471
cv->cv_magic = CV_MAGIC;
467-
VERIFY3S(pthread_cond_init(&cv->cv, NULL), ==, 0);
472+
VERIFY0(pthread_cond_init(&cv->cv, NULL));
468473
}
469474

470475
void
471476
cv_destroy(kcondvar_t *cv)
472477
{
473478
ASSERT3U(cv->cv_magic, ==, CV_MAGIC);
474-
VERIFY3S(pthread_cond_destroy(&cv->cv), ==, 0);
479+
VERIFY0(pthread_cond_destroy(&cv->cv));
475480
cv->cv_magic = 0;
476481
}
477482

@@ -481,9 +486,7 @@ cv_wait(kcondvar_t *cv, kmutex_t *mp)
481486
ASSERT3U(cv->cv_magic, ==, CV_MAGIC);
482487
ASSERT3P(mutex_owner(mp), ==, curthread);
483488
mp->m_owner = MTX_INIT;
484-
int ret = pthread_cond_wait(&cv->cv, &mp->m_lock);
485-
if (ret != 0)
486-
VERIFY3S(ret, ==, EINTR);
489+
VERIFY0(pthread_cond_wait(&cv->cv, &mp->m_lock));
487490
mp->m_owner = curthread;
488491
}
489492

@@ -497,7 +500,6 @@ cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
497500

498501
ASSERT3U(cv->cv_magic, ==, CV_MAGIC);
499502

500-
top:
501503
delta = abstime - ddi_get_lbolt();
502504
if (delta <= 0)
503505
return (-1);
@@ -519,10 +521,7 @@ cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
519521
if (error == ETIMEDOUT)
520522
return (-1);
521523

522-
if (error == EINTR)
523-
goto top;
524-
525-
VERIFY3S(error, ==, 0);
524+
VERIFY0(error);
526525

527526
return (1);
528527
}
@@ -536,10 +535,12 @@ cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,
536535
timestruc_t ts;
537536
hrtime_t delta;
538537

539-
ASSERT(flag == 0);
538+
ASSERT(flag == 0 || flag == CALLOUT_FLAG_ABSOLUTE);
539+
540+
delta = tim;
541+
if (flag & CALLOUT_FLAG_ABSOLUTE)
542+
delta -= gethrtime();
540543

541-
top:
542-
delta = tim - gethrtime();
543544
if (delta <= 0)
544545
return (-1);
545546

@@ -551,13 +552,10 @@ cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,
551552
error = pthread_cond_timedwait(&cv->cv, &mp->m_lock, &ts);
552553
mp->m_owner = curthread;
553554

554-
if (error == ETIME)
555+
if (error == ETIMEDOUT)
555556
return (-1);
556557

557-
if (error == EINTR)
558-
goto top;
559-
560-
ASSERT(error == 0);
558+
VERIFY0(error);
561559

562560
return (1);
563561
}
@@ -566,14 +564,14 @@ void
566564
cv_signal(kcondvar_t *cv)
567565
{
568566
ASSERT3U(cv->cv_magic, ==, CV_MAGIC);
569-
VERIFY3S(pthread_cond_signal(&cv->cv), ==, 0);
567+
VERIFY0(pthread_cond_signal(&cv->cv));
570568
}
571569

572570
void
573571
cv_broadcast(kcondvar_t *cv)
574572
{
575573
ASSERT3U(cv->cv_magic, ==, CV_MAGIC);
576-
VERIFY3S(pthread_cond_broadcast(&cv->cv), ==, 0);
574+
VERIFY0(pthread_cond_broadcast(&cv->cv));
577575
}
578576

579577
/*

0 commit comments

Comments
 (0)