Why is there e_drain_sx and e_drain_mtx?
Hans Petter Selasky
hps at selasky.org
Tue Dec 29 11:07:28 UTC 2020
On 12/29/20 11:49 AM, Sebastian Huber wrote:
> Hello,
>
> in the epoch based reclamation implementation we have
>
> struct epoch {
> struct ck_epoch e_epoch __aligned(EPOCH_ALIGN);
> epoch_record_t e_pcpu_record;
> int e_in_use;
> int e_flags;
> struct sx e_drain_sx;
> struct mtx e_drain_mtx;
> volatile int e_drain_count;
> const char *e_name;
> };
>
> The e_drain_sx and e_drain_mtx are only used in
>
> void
> epoch_drain_callbacks(epoch_t epoch)
> {
> ...
> DROP_GIANT();
>
> sx_xlock(&epoch->e_drain_sx);
> mtx_lock(&epoch->e_drain_mtx);
>
> ...
>
> mtx_unlock(&epoch->e_drain_mtx);
> sx_xunlock(&epoch->e_drain_sx);
>
> PICKUP_GIANT();
> }
>
> Why is there a combination of a shared/exclusive lock and a mutex used
> like this? Why is a single mutex insufficient?
>
Hi Sebastian,
The sx_xlock() is there because the operation may sleep and mutexes must
be dropped when sleeping. We only allow one drain at a time.
The mtx_lock() is there to make the operation atomic with regards to the
msleep/wakeup sequence. Search for the use of e_drain_mtx . Else the
msleep and wakeup calls may miss eachother.
How is the porting going otherwise? Do you see any performance
improvements using EPOCH?
--HPS
More information about the freebsd-hackers
mailing list