From owner-freebsd-current@freebsd.org Tue Mar 22 07:53:29 2016 Return-Path: Delivered-To: freebsd-current@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6F088AD83AA for ; Tue, 22 Mar 2016 07:53:29 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from kib.kiev.ua (kib.kiev.ua [IPv6:2001:470:d5e7:1::1]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 19C213F0 for ; Tue, 22 Mar 2016 07:53:28 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from tom.home (kostik@localhost [127.0.0.1]) by kib.kiev.ua (8.15.2/8.15.2) with ESMTPS id u2M7rN0H072089 (version=TLSv1 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO); Tue, 22 Mar 2016 09:53:24 +0200 (EET) (envelope-from kostikbel@gmail.com) DKIM-Filter: OpenDKIM Filter v2.10.3 kib.kiev.ua u2M7rN0H072089 Received: (from kostik@localhost) by tom.home (8.15.2/8.15.2/Submit) id u2M7rNBR072088; Tue, 22 Mar 2016 09:53:23 +0200 (EET) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: tom.home: kostik set sender to kostikbel@gmail.com using -f Date: Tue, 22 Mar 2016 09:53:23 +0200 From: Konstantin Belousov To: "Oleg V. Nauman" Cc: freebsd-current@freebsd.org Subject: Re: Fatal error 'mutex is on list' at line 139 in file /usr/src/lib/libthr/thread/thr_mutex.c (errno = 35) Message-ID: <20160322075323.GR1741@kib.kiev.ua> References: <5093647.qxI0C33PyG@asus.theweb.org.ua> <1541955.eeyoXZYkvP@asus.theweb.org.ua> <20160321112258.GM1741@kib.kiev.ua> <1850738.9W54HNFmp1@asus.theweb.org.ua> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1850738.9W54HNFmp1@asus.theweb.org.ua> User-Agent: Mutt/1.5.24 (2015-08-30) X-Spam-Status: No, score=-2.0 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FROM,NML_ADSP_CUSTOM_MED autolearn=no autolearn_force=no version=3.4.1 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on tom.home X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 22 Mar 2016 07:53:29 -0000 On Tue, Mar 22, 2016 at 08:06:17AM +0200, Oleg V. Nauman wrote: > After applying the patch: > > Mar 22 07:34:37 asus kernel: pid 1928 creating existing key 1 > Mar 22 07:34:58 asus kernel: pid 1928 (akonadi_baloo_index), uid 1001: exited > on signal 6 (core dumped) Good, thank you. Please try this one. diff --git a/lib/libthr/thread/thr_mutex.c b/lib/libthr/thread/thr_mutex.c index 3342c9f..865e4cf 100644 --- a/lib/libthr/thread/thr_mutex.c +++ b/lib/libthr/thread/thr_mutex.c @@ -38,6 +38,7 @@ * $FreeBSD$ */ +#include #include "namespace.h" #include #include @@ -264,6 +265,51 @@ set_inherited_priority(struct pthread *curthread, struct pthread_mutex *m) m->m_lock.m_ceilings[1] = -1; } +static void +shared_mutex_init(struct pthread_mutex *pmtx, const struct + pthread_mutex_attr *mutex_attr) +{ + static const struct pthread_mutex_attr foobar_mutex_attr = { + .m_type = PTHREAD_MUTEX_DEFAULT, + .m_protocol = PTHREAD_PRIO_NONE, + .m_ceiling = 0, + .m_pshared = PTHREAD_PROCESS_SHARED + }; + bool done; + + /* + * Hack to allow multiple pthread_mutex_init() calls on the + * same process-shared mutex. We rely on kernel allocating + * zeroed offpage for the mutex, i.e. the + * PMUTEX_INITSTAGE_ALLOC value must be zero. + */ + for (done = false; !done;) { + switch (pmtx->m_ps) { + case PMUTEX_INITSTAGE_DONE: + atomic_thread_fence_acq(); + done = true; + break; + case PMUTEX_INITSTAGE_ALLOC: + if (atomic_cmpset_int(&pmtx->m_ps, + PMUTEX_INITSTAGE_ALLOC, PMUTEX_INITSTAGE_BUSY)) { + if (mutex_attr == NULL) + mutex_attr = &foobar_mutex_attr; + mutex_init_body(pmtx, mutex_attr); + atomic_store_rel_int(&pmtx->m_ps, + PMUTEX_INITSTAGE_DONE); + done = true; + } + break; + case PMUTEX_INITSTAGE_BUSY: + _pthread_yield(); + break; + default: + PANIC("corrupted offpage"); + break; + } + } +} + int __pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutex_attr) @@ -285,7 +331,7 @@ __pthread_mutex_init(pthread_mutex_t *mutex, if (pmtx == NULL) return (EFAULT); *mutex = THR_PSHARED_PTR; - mutex_init_body(pmtx, *mutex_attr); + shared_mutex_init(pmtx, *mutex_attr); return (0); } @@ -426,6 +472,7 @@ check_and_init_mutex(pthread_mutex_t *mutex, struct pthread_mutex **m) *m = __thr_pshared_offpage(mutex, 0); if (*m == NULL) ret = EINVAL; + shared_mutex_init(*m, NULL); } else if (__predict_false(*m <= THR_MUTEX_DESTROYED)) { if (*m == THR_MUTEX_DESTROYED) { ret = EINVAL; @@ -588,6 +635,7 @@ _pthread_mutex_unlock(pthread_mutex_t *mutex) mp = __thr_pshared_offpage(mutex, 0); if (mp == NULL) return (EINVAL); + shared_mutex_init(mp, NULL); } else { mp = *mutex; } @@ -815,6 +863,7 @@ _pthread_mutex_getprioceiling(pthread_mutex_t *mutex, m = __thr_pshared_offpage(mutex, 0); if (m == NULL) return (EINVAL); + shared_mutex_init(m, NULL); } else { m = *mutex; if (m <= THR_MUTEX_DESTROYED) @@ -839,6 +888,7 @@ _pthread_mutex_setprioceiling(pthread_mutex_t *mutex, m = __thr_pshared_offpage(mutex, 0); if (m == NULL) return (EINVAL); + shared_mutex_init(m, NULL); } else { m = *mutex; if (m <= THR_MUTEX_DESTROYED) @@ -942,12 +992,13 @@ __pthread_mutex_setyieldloops_np(pthread_mutex_t *mutex, int count) int _pthread_mutex_isowned_np(pthread_mutex_t *mutex) { - struct pthread_mutex *m; + struct pthread_mutex *m; if (*mutex == THR_PSHARED_PTR) { m = __thr_pshared_offpage(mutex, 0); if (m == NULL) return (0); + shared_mutex_init(m, NULL); } else { m = *mutex; if (m <= THR_MUTEX_DESTROYED) diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h index 7ee1fbf..0db2dad 100644 --- a/lib/libthr/thread/thr_private.h +++ b/lib/libthr/thread/thr_private.h @@ -146,6 +146,13 @@ TAILQ_HEAD(mutex_queue, pthread_mutex); #define MAX_DEFER_WAITERS 50 +/* + * Values for pthread_mutex m_ps indicator. + */ +#define PMUTEX_INITSTAGE_ALLOC 0 +#define PMUTEX_INITSTAGE_BUSY 1 +#define PMUTEX_INITSTAGE_DONE 2 + struct pthread_mutex { /* * Lock for accesses to this structure. @@ -156,6 +163,7 @@ struct pthread_mutex { int m_count; int m_spinloops; int m_yieldloops; + int m_ps; /* pshared init stage */ /* * Link for all mutexes a thread currently owns, of the same * prio type.