All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>,
	 Stefan Hajnoczi <stefanha@redhat.com>,
	qemu-devel <qemu-devel@nongnu.org>
Subject: Re: [PATCH 4/4] coroutine: Break inclusion loop
Date: Mon, 19 Dec 2022 05:23:24 +0100	[thread overview]
Message-ID: <87o7s010oz.fsf@pond.sub.org> (raw)
In-Reply-To: <49afb7cb-c3e0-2966-65aa-2ead9c2e7d9d@redhat.com> (Paolo Bonzini's message of "Sat, 17 Dec 2022 13:42:01 +0100")

Paolo Bonzini <pbonzini@redhat.com> writes:

> On 12/15/22 07:49, Markus Armbruster wrote:
>>> linux-user/ does not use coroutines, so I'd like to avoid that it
>>> includes qemu/coroutine.h.
>> They include it even before the patch, via lockable.h.
>
> They do but there's a difference between "including lockable.h and implictly getting coroutine.h due to dependencies" and "including 
> coroutine.h when you really wanted QEMU_LOCK_GUARD()".
>
>> My patch actually enables*not*  including coroutine.h: with it applied,
>> including lockable.h no longer gets you coroutine.h as well.
>> If you include lockable.h and make use of certain macros, the compile
>> fails, and you fix it by including coroutine.h instead like pretty much
>> everything else.  Is this really too objectionable to be committed?
>
> s/certain macros/all macros/.  All you can do is qemu_lockable_lock/unlock, which is the less common usage of 
> qemu/lockable.h:
>
> - qemu_lockable_lock/unlock: used in include/qemu/seqlock.h, tests/unit/test-coroutine.c, util/qemu-coroutine-lock.c
>
> - QEMU_LOCK_GUARD and WITH_QEMU_LOCK_GUARD are used in 49 files.
>
>>>> 1) qemu/coroutine.h keeps including qemu/lockable.h
>>
>> As in my patch.
>
> That's where the similarity ends. :)
>
>>>> 2) qemu/lockable.h is modified as follows to omit the reference to CoMutex:
>>>>
>>>> diff --git a/include/qemu/lockable.h b/include/qemu/lockable.h
>>>> index 86db7cb04c9c..db59656538a4 100644
>>>> --- a/include/qemu/lockable.h
>>>> +++ b/include/qemu/lockable.h
>>>> @@ -71,9 +71,11 @@ qemu_null_lockable(void *x)
>>>>                 void *: qemu_null_lockable(x),                             \
>>>>                 QemuMutex *: qemu_make_lockable(x, QML_OBJ_(x, mutex)),    \
>>>>                 QemuRecMutex *: qemu_make_lockable(x, QML_OBJ_(x,
>>>> rec_mutex)), \
>>>> -             CoMutex *: qemu_make_lockable(x, QML_OBJ_(x, co_mutex)),   \
>>>> +             QEMU_MAKE_CO_MUTEX_LOCKABLE(x)                             \
>>>>                 QemuSpin *: qemu_make_lockable(x, QML_OBJ_(x, spin)))
>>>>
>>>> +#define QEMU_MAKE_CO_MUTEX_LOCKABLE(x)
>>>> +
>>>>    /**
>>>>     * QEMU_MAKE_LOCKABLE_NONNULL - Make a polymorphic QemuLockable
>>>>     *
>>>>
>>>> 3) the following hack is added in qemu/coroutine.h, right after including
>>>> qemu/lockable.h:
>>>>
>>>> #undef QEMU_MAKE_CO_MUTEX_LOCKABLE(x)
>>>> #define QEMU_MAKE_CO_MUTEX_LOCKABLE(x) \
>>>>                CoMutex *: qemu_make_lockable(x, QML_OBJ_(x, co_mutex)),
>>
>> Let me see...  if I include just lockable.h and make use of certain
>> (generic) macro(s), the macro(s) won't have a case for QemuMutex *.
>> Using them with a QemuMutex * argument won't compile.
>
> s/QemuMutex/CoMutex/.  That is, you get the CoMutex case only if you include qemu/coroutine.h.  Which you probably did anyway, because 
> CoMutexes are almost always embedded (not used as pointers).  In fact I suspect the above trick also makes it possible to remove CoMutex from 
> qemu/typedefs.h.
>
> Furthermore, using qemu_lockable_lock/unlock with CoMutexes still works, even if you don't include qemu/coroutine.h, just like in your patch.
>
>>>> Neither is particularly pretty, so I vote for leaving things as is with
>>>> a comment above the two #include directives.
>>
>> Inlusion loops are landmines.  Evidence: the compilation failure Phil
>> ran in, leading to his
>>      Subject: [PATCH-for-8.0] coroutine: Add missing <qemu/atomic.h> include
>>      Message-Id:<20221125175532.48858-1-philmd@linaro.org>
>> Your macro hack I find too off-putting 😄
>
> I think the macro is much better than nerfing qemu/lockable.h.

The core of the problem is that lockable.h wants to provide _Generic()
with a CoMutex case if CoMutex exists.

The solution you proposed approximates this as follows.  lockable.h
makes the case configurable, default off.  coroutine.h configures it to
on, and includes lockable.h.  Works as long as we include only
coroutine.h, or coroutine.h before lockable.h.  Falls apart if we
include lockable.h, and only then coroutine.h.

For a robust solution, we'd need to enable lockable.h to detect "this
compilation unit may use coroutines".  Could CONFIG_USB_ONLY be pressed
into service?

> Another alternative is to add a new header qemu/lockable-protos.h and move qemu_co_mutex_{lock,unlock} there (possibly other prototypes as 
> well).  Then include it from both qemu/lockable.h and qemu/coroutine.h.

Only from lockable.h, because coroutine.h gets it via lockable.h, right?

Lazy^Wpragmatic solution: move the coroutine.h parts lockable.h needs to
lockable.h.  As far as I can tell:

    typedef CoMutex (unless we keep it in typedefs.h)
    qemu_co_mutex_lock()
    qemu_co_mutex_unlock()

Could throw in

    qemu_co_mutex_init()
    qemu_co_mutex_assert_locked()

to avoid splitting the co_mutex interface.

If keeping this in lockable.h bothers you, we could create comutex.h for
it.

Can't see what adding more to the new header would buy us (other than
arguments on how to name it).  Happy to be enlightened there, of course.



  reply	other threads:[~2022-12-19  4:24 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-08 14:23 [PATCH 0/4] coroutine: Clean up includes Markus Armbruster
2022-12-08 14:23 ` [PATCH 1/4] coroutine: Clean up superfluous inclusion of qemu/coroutine.h Markus Armbruster
2022-12-08 14:59   ` Stefan Hajnoczi
2022-12-08 17:56     ` Markus Armbruster
2022-12-08 14:23 ` [PATCH 2/4] coroutine: Move coroutine_fn to qemu/osdep.h, trim includes Markus Armbruster
2022-12-08 15:03   ` Stefan Hajnoczi
2022-12-08 14:23 ` [PATCH 3/4] coroutine: Clean up superfluous inclusion of qemu/lockable.h Markus Armbruster
2022-12-08 15:05   ` Stefan Hajnoczi
2022-12-08 14:23 ` [PATCH 4/4] coroutine: Break inclusion loop Markus Armbruster
2022-12-08 15:07   ` Stefan Hajnoczi
     [not found]   ` <2ac0daae-da25-0a31-9a73-8f186cc510e9@redhat.com>
2022-12-13  0:34     ` Paolo Bonzini
2022-12-15  6:49       ` Markus Armbruster
2022-12-17 12:42         ` Paolo Bonzini
2022-12-19  4:23           ` Markus Armbruster [this message]
2022-12-17 17:23       ` Philippe Mathieu-Daudé

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87o7s010oz.fsf@pond.sub.org \
    --to=armbru@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.