All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC] Introducing CoroCheck and proposal for a blocking_fn annotation
@ 2013-09-06 14:30 Gabriel Kerneis
  2013-09-06 14:30 ` [Qemu-devel] [RFC] Introduce " Gabriel Kerneis
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Gabriel Kerneis @ 2013-09-06 14:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, stefanha, pbonzini, Gabriel Kerneis, charlie

During his GSoC on writing a CPC [1] backend for QEMU, Charlie Shepherd
started to explicitly annotate coroutine_fn [2]. On aspect of this
refactoring work has been to split "dynamic" functions (that used
qemu_in_coroutine) into a blocking version and a coroutine one. It has
been agreed that it was a positive change, at least by some people who
considered dynamic function a bit hackish, but it has an obvious
downside: if one mistakenly call the blocking version from a coroutine
function, the main loop might block for a long time. The risk is
mitigated by suffix blocking function's name with _sync and other
tricks, but it is not a very reliable, long-term solution.

To help Charlie's large-scale refactoring, I have written a small tool,
CoroCheck [3], that performs a static analysis of QEMU and checks that
coroutine_fn annotations actually make sense.

More precisely, here is what CoroCheck does for each file of QEMU:
- assuming annotations in headers and typedef are correct, compute the
  minimal set of functions that should be annotated with coroutine_fn,
- warn about function pointer casts and assignments that introduce or
  remove coroutine_fn annotations,
- warn about missing or spurious coroutine_fn annotations,
- produce a .dot file that can be processed with graphviz to produce a
  pdf of the annotated call graph (with wrong annotations showing up in
  red - this still needs to be documented properly).

To learn how to analyse QEMU with CoroCheck, see CoroCheck's README [4].

    On a related note, #define coroutine_fn and #define blocking_fn
    should probably be surrounded by #ifndef to allow easy redefinition
    using ./configure --extra-cflags="-Dcoroutine_fn='…'"  I'll leave
    that follow-up patch as an exercise for Charlie ;-)

Charlie asked me to add a functionality to CoroCheck enabling him to
annotate blocking functions, and warn if they were called from coroutine
ones. CoroCheck now also supports this functionality.

For the reasons outlined in my first paragraph, I think that annotating
blocking functions is important for QEMU at large. It would be a pity
that Charlie wastes his time annotating functions locally, and that this
valuable piece of documentation is lost when he submits his patches.

The attached patch does not actually annotate any function, but it paves
the way for such future annotations. This is more a design choice than a
technical issue, and I hope a consensus can be reached soon enough to
allow Charlie to use it in his next patch series.

Note that CoroCheck has been written as a plugin to CIL [5]. Contrary to
CPC, which is still somewhat of a prototype (although a pretty good
one!), CIL is a solid piece of software, packaged in both Fedora and
(very soon) Debian. CoroCheck makes use of the CIL plugin facility which
has not made its way into a released version yet, but this should happen
in the next few months. Therefore, in a not-too-distant future, it is
reasonable to imagine that static checking of QEMU coroutine_fn
annotations could be (an optional) part of QEMU test suite. Adding
blocking_fn annotations would make even more sense in this context.

Best regards,
Gabriel

[1] https://github.com/kerneis/cpc
[2] http://lists.nongnu.org/archive/html/qemu-devel/2013-08/msg00529.html
[3] https://github.com/kerneis/corocheck
[4] https://github.com/kerneis/corocheck#qemu
[5] http://kerneis.github.io/cil/

Gabriel Kerneis (1):
  Introduce blocking_fn annotation

 include/block/coroutine.h |   23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

-- 
1.7.10.4

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] [RFC] Introduce blocking_fn annotation
  2013-09-06 14:30 [Qemu-devel] [RFC] Introducing CoroCheck and proposal for a blocking_fn annotation Gabriel Kerneis
@ 2013-09-06 14:30 ` Gabriel Kerneis
  2013-09-06 14:46 ` [Qemu-devel] [RFC] Introducing CoroCheck and proposal for a " Gabriel Kerneis
  2013-09-06 15:36 ` Charlie Shepherd
  2 siblings, 0 replies; 6+ messages in thread
From: Gabriel Kerneis @ 2013-09-06 14:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, stefanha, pbonzini, Gabriel Kerneis, charlie

A blocking function is a function that must not be called in coroutine
context, for example because it might block for a long amount of time.
This annotation should be used to mark normal functions that have a
coroutine_fn counterpart, to make sure that the former is not used
instead of the later in coroutine context.

Signed-off-by: Gabriel Kerneis <gabriel@kerneis.info>
---
 include/block/coroutine.h |   23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/include/block/coroutine.h b/include/block/coroutine.h
index 4232569..a92d14f 100644
--- a/include/block/coroutine.h
+++ b/include/block/coroutine.h
@@ -46,6 +46,29 @@
  */
 #define coroutine_fn
 
+/**
+ * Mark a function that executes in blocking context
+ *
+ * Functions that execute in blocking context cannot be called directly from
+ * coroutine functions.  In the future it would be nice to enable compiler or
+ * static checker support for catching such errors.  This annotation might make
+ * it possible and in the meantime it serves as documentation.
+ *
+ * Annotating a function as "blocking" is stronger than having a mere
+ * (unannotated) normal function. It means that it might block the main
+ * loop for a significant amount of time, and therefore must not be
+ * called in coroutine context. In general, its hints that an
+ * alternative coroutine function performing the same taks is available
+ * for use in coroutine context.
+ *
+ * For example:
+ *
+ *   static void blocking_fn foo(void) {
+ *       ....
+ *   }
+ */
+#define blocking_fn
+
 typedef struct Coroutine Coroutine;
 
 /**
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [RFC] Introducing CoroCheck and proposal for a blocking_fn annotation
  2013-09-06 14:30 [Qemu-devel] [RFC] Introducing CoroCheck and proposal for a blocking_fn annotation Gabriel Kerneis
  2013-09-06 14:30 ` [Qemu-devel] [RFC] Introduce " Gabriel Kerneis
@ 2013-09-06 14:46 ` Gabriel Kerneis
  2013-09-06 15:36 ` Charlie Shepherd
  2 siblings, 0 replies; 6+ messages in thread
From: Gabriel Kerneis @ 2013-09-06 14:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, stefanha, pbonzini, charlie

On Fri, Sep 06, 2013 at 03:30:38PM +0100, Gabriel Kerneis wrote:
> More precisely, here is what CoroCheck does for each file of QEMU:
> - produce a .dot file that can be processed with graphviz to produce a
>   pdf of the annotated call graph (with wrong annotations showing up in
>   red - this still needs to be documented properly).

For those of you interested in finding out what those graphs look like,
I have uploaded the result for qemu-coroutine-lock.c here:
http://www.scribd.com/doc/166033638/qemu-coroutine-lock-c

As explained on the right:
  - Square = should be coroutine_fn
  - Circle = need not be coroutine_fn
  - Dashed red = wrong annotation (either missing or spurious)

Best regards,
-- 
Gabriel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [RFC] Introducing CoroCheck and proposal for a blocking_fn annotation
  2013-09-06 14:30 [Qemu-devel] [RFC] Introducing CoroCheck and proposal for a blocking_fn annotation Gabriel Kerneis
  2013-09-06 14:30 ` [Qemu-devel] [RFC] Introduce " Gabriel Kerneis
  2013-09-06 14:46 ` [Qemu-devel] [RFC] Introducing CoroCheck and proposal for a " Gabriel Kerneis
@ 2013-09-06 15:36 ` Charlie Shepherd
  2013-09-06 16:05   ` Gabriel Kerneis
  2 siblings, 1 reply; 6+ messages in thread
From: Charlie Shepherd @ 2013-09-06 15:36 UTC (permalink / raw)
  To: Gabriel Kerneis; +Cc: kwolf, stefanha, qemu-devel, pbonzini

On 06/09/2013 15:30, Gabriel Kerneis wrote:
> Note that CoroCheck has been written as a plugin to CIL [5]. Contrary to
> CPC, which is still somewhat of a prototype (although a pretty good
> one!), CIL is a solid piece of software, packaged in both Fedora and
> (very soon) Debian. CoroCheck makes use of the CIL plugin facility which
> has not made its way into a released version yet, but this should happen
> in the next few months. Therefore, in a not-too-distant future, it is
> reasonable to imagine that static checking of QEMU coroutine_fn
> annotations could be (an optional) part of QEMU test suite. Adding
> blocking_fn annotations would make even more sense in this context.

I definitely think static checking of coroutine_fn annotations is the 
only way to ensure that the QEMU tree is coroutine safe. I think Stefan 
mentioned a bug that occurred previously due to a function that expected 
to be called in a coroutine context being called normally.

However, I'm not sure it makes sense to use blocking_fn until the 
convert-block series (which currently needs a respin after Stefan's 
review) is fully upstreamed. Maybe this patch makes most sense at the 
start of that series?


Charlie

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [RFC] Introducing CoroCheck and proposal for a blocking_fn annotation
  2013-09-06 15:36 ` Charlie Shepherd
@ 2013-09-06 16:05   ` Gabriel Kerneis
  2013-09-06 16:28     ` Kevin Wolf
  0 siblings, 1 reply; 6+ messages in thread
From: Gabriel Kerneis @ 2013-09-06 16:05 UTC (permalink / raw)
  To: Charlie Shepherd; +Cc: kwolf, stefanha, qemu-devel, pbonzini

On Fri, Sep 06, 2013 at 04:36:47PM +0100, Charlie Shepherd wrote:
> However, I'm not sure it makes sense to use blocking_fn until the
> convert-block series (which currently needs a respin after Stefan's
> review) is fully upstreamed. Maybe this patch makes most sense at
> the start of that series?

Yes, definitely, that's why I labeled it RFC rather than PATCH. But if
people agree, it would make much more sense to have the annotations
within your patch series rather than added later (notwithstanding the
fact that it would ease your refactoring effort).

Best,
-- 
Gabriel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [RFC] Introducing CoroCheck and proposal for a blocking_fn annotation
  2013-09-06 16:05   ` Gabriel Kerneis
@ 2013-09-06 16:28     ` Kevin Wolf
  0 siblings, 0 replies; 6+ messages in thread
From: Kevin Wolf @ 2013-09-06 16:28 UTC (permalink / raw)
  To: Gabriel Kerneis; +Cc: Charlie Shepherd, pbonzini, qemu-devel, stefanha

Am 06.09.2013 um 18:05 hat Gabriel Kerneis geschrieben:
> On Fri, Sep 06, 2013 at 04:36:47PM +0100, Charlie Shepherd wrote:
> > However, I'm not sure it makes sense to use blocking_fn until the
> > convert-block series (which currently needs a respin after Stefan's
> > review) is fully upstreamed. Maybe this patch makes most sense at
> > the start of that series?
> 
> Yes, definitely, that's why I labeled it RFC rather than PATCH. But if
> people agree, it would make much more sense to have the annotations
> within your patch series rather than added later (notwithstanding the
> fact that it would ease your refactoring effort).

Makes sense to me, go ahead and put it to use.

Kevin

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-09-06 16:28 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-09-06 14:30 [Qemu-devel] [RFC] Introducing CoroCheck and proposal for a blocking_fn annotation Gabriel Kerneis
2013-09-06 14:30 ` [Qemu-devel] [RFC] Introduce " Gabriel Kerneis
2013-09-06 14:46 ` [Qemu-devel] [RFC] Introducing CoroCheck and proposal for a " Gabriel Kerneis
2013-09-06 15:36 ` Charlie Shepherd
2013-09-06 16:05   ` Gabriel Kerneis
2013-09-06 16:28     ` Kevin Wolf

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.