Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 19 Aug 2007 14:53:53 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Pawel Jakub Dawidek <pjd@FreeBSD.org>
Cc:        freebsd-arch@FreeBSD.org
Subject:   Re: Lockless uidinfo.
Message-ID:  <20070819142214.O34036@delplex.bde.org>
In-Reply-To: <20070818220756.GH6498@garage.freebsd.pl>
References:  <20070818120056.GA6498@garage.freebsd.pl> <20070818220756.GH6498@garage.freebsd.pl>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 19 Aug 2007, Pawel Jakub Dawidek wrote:

> Two more things...
>
>> The patch below remove per-uidinfo locks:
>>
>> 	http://people.freebsd.org/~pjd/patches/uidinfo_lockless.patch
>
> We could upgrade from lock-free algorithm I used here to wait-free
> algorithm, but we don't have atomic_fetchadd_long(). How hard will it be
> to implement it?
>
> We could then change:
>
> 	do {
> 		old = uip->ui_proccnt;
> 		if (old + diff > max)
> 			return (0);
> 	} while (atomic_cmpset_long(&uip->ui_proccnt, old, old + diff) == 0);
>
> to something like this:
>
> 	if (atomic_fetchadd_long(&uip->ui_proccnt, diff) + diff > max) {
> 		atomic_subtract_long(&uip->ui_proccnt, diff);
> 		return (0);
> 	}

atomic_*long() shouldn't exist (and doesn't exist in my version) since
longs should actually be long (twice as long as registers) and thus
especially epensive to lock.

long is just a bogus historical type for ui_proccnt (in case int is
16 bits, and the null set of old systems with 16-bit ints have non-old
CPU resources for >= 65536 processes per user).  There are several
variables like this.  This causes problems spelling atomic accesses to
such variables.  Sometimes on 64-bit machines, asking for a long
(128 bits) is actually useful for the bogus reason that long has the
wrong size (64 bits) and 64-bits is actually useful on 64-bit machines
though not needed on 32-bit machines.

>> I needed to change ui_sbsize from rlim_t (64bit) to long, because we
>> don't have 64bit atomics on all archs, and because sbsize represents
>> size in bytes, it can't go beyond 32bit on 32bit archs (PAE might be a
>> bit of a problem).

This problem is similar.  rlim_t is 64 bits since 64 bits is needed for
a few limits and 128 bits isn't needed yet, so the same type is used for
all limits.  This causes problems locking it even on 64-bit machines
where longs have the wrong size (not 2*64), since although 64-bit machines
have 64-bit atomics, there is no good way to spell the atomic accesses to
an rlim_t.  On 32-bit machines, there is no way at all to spell the atomic
accesses to an rlim_t.  Here the spelling problems prevent misuse of atomics
on longs.

Otherwise, the type for a size should be something like vm_size_t, and
then the problem is the spelling of atomic accesses to vm_size_t's.  This
problem is handled for pointers by type-punning pointers to ints or
longs in <machine/atomic.h>.  (The amd64 atomic.h uses longs.  It
should use int64_t or register_t.  It uses 8-bit DOS/Windowspeak
"Operations on 32-bit double words" and "Operations on 64-bit quad
words" in comments copied from the i386 version.  On 64-bit machines,
32 bits is half a word, not a double word...)

Bruce



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