Page MenuHomeFreeBSD

Inline critical_enter/exit for amd64
AbandonedPublic

Authored by mjg on May 23 2018, 5:16 AM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Apr 30, 5:17 PM
Unknown Object (File)
Dec 23 2023, 2:40 AM
Unknown Object (File)
Oct 12 2023, 7:50 AM
Unknown Object (File)
Sep 11 2023, 10:56 AM
Unknown Object (File)
Sep 4 2023, 8:20 AM
Unknown Object (File)
Aug 27 2023, 6:52 AM
Unknown Object (File)
Aug 13 2023, 6:13 AM
Unknown Object (File)
Jun 20 2023, 8:34 AM
Subscribers

Details

Reviewers
kib
Summary

Header solution is rather significant and I gave up on an attempt to clean it up. This has as two-fold side effect:

  • a separate struct is defined which "knows" about relevant offsets
  • the thing is opt in

struct thread got reorganized to keep frequently modified fields together.

Attempts to make the change mandatory cause compilation failures on a number of archs as 'current' is not exposed and I failed to find an easy way to fix that.

I don't feel strongly about the way this is done whatsoever, I just want inlined critical_* which are usable from sys/mutex.h.

Test Plan

universe has the same failures before and after

boots and works fine with and without debug

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 16778

Event Timeline

Hmm, so the problem is actually in the fact that sys/systm.h is typically included before sys/proc.h.

Did you tried to move everything related to critical sections, into sys/proc.h ? If some code needs critical section, it typically needs the curthread fields accesses as well.

I noted I have a use for this in mutex code, but mutexes are included by proc.h which creates a lot of dependency fun. An attempt to create _thread.h failed as there is just too much work.

I don't remember other examples, but there is a surprising amount of places which do critical_* and can't afford to pull in proc.h. I tested it out some time earlier with a variant where if proc.h is included, the primitives are inlines and out of line otherwise - the latter was quite widespread.

In D15531#327934, @mjg wrote:

I noted I have a use for this in mutex code, but mutexes are included by proc.h which creates a lot of dependency fun.

And if you use macro instead of the inline function, does it help ? Macros postpone the dependency requirements, so you can provide struct thread definition after the macro definition, which is not possible with inlines.

I tried that. Some mutex users can't affort to pull in proc.h either. The motivation here is to provide mutex unlock without atomics, which requires partial access to thread layout.

In D15531#327944, @mjg wrote:

I tried that. Some mutex users can't affort to pull in proc.h either. The motivation here is to provide mutex unlock without atomics, which requires partial access to thread layout.

Which mutex users ? Show an example.

Basically, if the ordering/macro tricks do not work, I do not see why not do something like

static inline void
critical_exit(void)
{
  int *td_critnest_p;
  u_char *td_owepreempt_p;
  td_critnest_p = (char *)curthread + TD_CRITNEST_OFFSET;
  td_owepreempt_p = (char *)curthread + TD_OWEPREEMPT_OFFSET;
  (*td_critnest_p)--;
  ...
}

and somewhere else

_Static_assert(TD_CRITNEST_OFFSET == __offsetof(struct thread, td_critnest, "BOOM");

This can be done for all arches and is much less hackish then half-done thread_lite.

genassm already generates these and many other offsets. It would be better to do that than manual constants. There would be a little bit of extra build work to make this happen but it should be trivial. We would also need to assert that sizes and types are correct somewhere. The generator could generate both offset and type information for required fields however.

A different variant went in with r335879