Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Feb 2011 14:02:21 -0500
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-hackers@freebsd.org
Cc:        Dmitry Krivenok <krivenok.dmitry@gmail.com>
Subject:   Re: mtx_init/lock_init and uninitialized struct mtx
Message-ID:  <201102241402.21556.jhb@freebsd.org>
In-Reply-To: <AANLkTimGkjDLO7LCgPMKyDGeWTqKZzzFk=bPzkBCfUn6@mail.gmail.com>
References:  <AANLkTimGkjDLO7LCgPMKyDGeWTqKZzzFk=bPzkBCfUn6@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thursday, February 24, 2011 10:47:27 am Dmitry Krivenok wrote:
> Hello Hackers,
>=20
> Is it allowed to call mtx_init on a mutex defined as an auto variable
> and not initialized explicitly, i.e.:

It does expect you to zero it first.  I've considered adding a MTX_NEW flag=
 to=20
disable this check for places where the developer knows it is safe.  Most=20
mutexes are allocated in an already-zero'd structure or BSS as Patrick note=
d,
so they are already correct.  It is a trade off between catching double=20
initializations and requiring extra M_ZERO flags or bzero() calls in variou=
s=20
places.

> static int foo()
> {
>    struct mtx m;  // Uninitialized auto variable, so it's value is=20
undefined.
>    mtx_init(&m, "my_mutex", NULL, MTX_DEF);
>    =85
>    // Do something
>    ...
>    mtx_destroy(&m);
>    return 0;
> }
>=20
> I encountered a problem with such code on a kernel compiled with
> INVARIANTS option.
> The problem is that mtx_init calls lock_init(&m->lock_object) and
> lock_init, in turn, calls:
>=20
>  79         /* Check for double-init and zero object. */
>  80         KASSERT(!lock_initalized(lock), ("lock \"%s\" %p already
> initialized",
>  81             name, lock));
>=20
> lock_initialized() just checks that a bit is set in lo_flags field of
> struct lock_object:
>=20
> 178 #define lock_initalized(lo)     ((lo)->lo_flags & LO_INITIALIZED)
>=20
> However, the structure containing this field is never initialized
> (neither in mtx_init nor in lock_init).
> So, assuming that the mutex was defined as auto variable, the content
> of lock_object field of struct mtx
> is also undefined:
>=20
>  37 struct mtx {
>  38         struct lock_object      lock_object;    /* Common lock
> properties. */
>  39         volatile uintptr_t      mtx_lock;       /* Owner and flags. */
>  40 };
>=20
> In some cases, the initial value of lo_flags _may_ have the
> "initialized" bit set and KASSERT will call panic.
>=20
> Is it user's responsibility to properly (how exactly?) initialize
> struct mtx, e.g.
> memset(&m, '\0', sizeof(struct mtx));
>=20
> Or should mtx_init() explicitly initialize all fields of struct mtx?
>=20
> Thanks in advance!
>=20
> --=20
> Sincerely yours, Dmitry V. Krivenok
> e-mail: krivenok.dmitry@gmail.com
> skype: krivenok_dmitry
> jabber: krivenok_dmitry@jabber.ru
> icq: 242-526-443
> _______________________________________________
> freebsd-hackers@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"
>=20

=2D-=20
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201102241402.21556.jhb>