Re: [PULL 00/11] capstone + disassembler patch queue

2020-09-23 Thread Paolo Bonzini
On 22/09/20 19:47, Richard Henderson wrote:
> The following changes since commit 834b9273d5cdab68180dc8c84d641aaa4344b057:
> 
>   Merge remote-tracking branch 
> 'remotes/vivier2/tags/trivial-branch-for-5.2-pull-request' into staging 
> (2020-09-22 15:42:23 +0100)
> 
> are available in the Git repository at:
> 
>   https://github.com/rth7680/qemu.git tags/pull-cap-20200922
> 
> for you to fetch changes up to fcfea6ced053045beb1dc8d22bdeaacc9c03d0b9:
> 
>   disas/capstone: Add skipdata hook for s390x (2020-09-22 08:59:28 -0700)
> 
> 
> Update capstone submodule from v3.0.5 to v5 ("next").
> Convert submodule build to meson.
> Enable capstone disassembly for s390x.
> Code cleanups in disas.c
> 
> 
> Richard Henderson (11):
>   capstone: Convert Makefile bits to meson bits
>   capstone: Update to upstream "next" branch
>   capstone: Require version 4.0 from a system library
>   disas: Move host asm annotations to tb_gen_code
>   disas: Clean up CPUDebug initialization
>   disas: Use qemu/bswap.h for bfd endian loads
>   disas: Cleanup plugin_disas
>   disas: Configure capstone for aarch64 host without libvixl
>   disas: Split out capstone code to disas/capstone.c
>   disas: Enable capstone disassembly for s390x
>   disas/capstone: Add skipdata hook for s390x
> 
>  configure |  64 +
>  Makefile  |  16 --
>  meson.build   | 124 +++-
>  include/disas/dis-asm.h   | 104 +++
>  include/disas/disas.h |   2 +-
>  include/exec/log.h|   4 +-
>  accel/tcg/translate-all.c |  24 +-
>  disas.c   | 707 
> +++---
>  disas/capstone.c  | 326 +
>  target/s390x/cpu.c|   4 +
>  tcg/tcg.c |   4 +-
>  capstone  |   2 +-
>  disas/meson.build |   1 +
>  meson_options.txt |   4 +
>  14 files changed, 681 insertions(+), 705 deletions(-)
>  create mode 100644 disas/capstone.c
> 

I will pull this as well into my branch (as a kind of topic branch) to
avoid further conflicts.

Paolo




Re: [PATCH v8 3/7] usb/hcd-xhci: Split pci wrapper for xhci base model

2020-09-23 Thread Gerd Hoffmann
  Hi,

> Can you also provide any steps to test vmstate migration ?

Helper script below, run it with something like:

$script -m 4G -vga std \
  -cdrom Fedora-Workstation-Live-x86_64-32-1.6.iso \
  -device qemu-xhci -device usb-tablet

 cut here ==
#!/bin/bash

# most recent release
src="/usr/local/bin/qemu-system-x86_64" 

# master branch / devel branch
dst="/home/kraxel/projects/qemu/build/default/x86_64-softmmu/qemu-system-x86_64"

# time to wait before migration
sec=60

# vmstate storage
tmp="$(mktemp ${TMPDIR-/var/tmp}/vmstate-XX)"
trap "rm -f $tmp" EXIT

# figure machine type to use
machine=$($src -M help | awk '/default/ { print $1 }')
machine="${machine},vmport=off"
machine="${machine},accel=kvm"



echo "#"
echo "# vmsave (after $sec seconds)"
echo "#"
(
sleep $sec
echo "migrate_set_speed 100M"
echo "migrate exec:cat>$tmp"
echo "quit"
) |\
$src -nodefaults \
-monitor stdio \
-M $machine \
"$@"

echo "#"
echo "# vmload"
echo "#"
$dst -nodefaults \
-monitor stdio \
-incoming "exec:cat $tmp" \
-M $machine \
"$@"




Re: [PATCH v2 1/3] hw/smbios: support loading OEM strings values from a file

2020-09-23 Thread Laszlo Ersek
Hi Daniel,

On 09/23/20 12:41, Daniel P. Berrangé wrote:
> Some applications want to pass quite large values for the OEM strings
> entries. Rather than having huge strings on the command line, it would
> be better to load them from a file, as supported with -fw_cfg.
> 
> This introduces the "path" parameter allowing for:
> 
>   $ echo -n "thisthing" > mydata.txt
>   $ qemu-system-x86_64 \
> -smbios type=11,value=something \
> -smbios type=11,path=mydata.txt \
> -smbios type=11,value=somemore \
> ...other args...
> 
> Now in the guest
> 
> $ dmidecode -t 11
> Getting SMBIOS data from sysfs.
> SMBIOS 2.8 present.
> 
> Handle 0x0E00, DMI type 11, 5 bytes
> OEM Strings
>   String 1: something
>   String 2: thisthing
>   String 3: somemore
> 
> Reviewed-by: Philippe Mathieu-Daudé 
> Signed-off-by: Daniel P. Berrangé 
> ---
>  hw/smbios/smbios.c | 72 +-
>  1 file changed, 59 insertions(+), 13 deletions(-)
> 
> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> index 7cc950b41c..8450fad285 100644
> --- a/hw/smbios/smbios.c
> +++ b/hw/smbios/smbios.c
> @@ -110,7 +110,7 @@ static struct {
>  
>  static struct {
>  size_t nvalues;
> -const char **values;
> +char **values;
>  } type11;
>  
>  static struct {
> @@ -314,6 +314,11 @@ static const QemuOptDesc qemu_smbios_type11_opts[] = {
>  .type = QEMU_OPT_STRING,
>  .help = "OEM string data",
>  },
> +{
> +.name = "path",
> +.type = QEMU_OPT_STRING,
> +.help = "OEM string data from file",
> +},
>  };
>  
>  static const QemuOptDesc qemu_smbios_type17_opts[] = {
> @@ -641,6 +646,8 @@ static void smbios_build_type_11_table(void)
>  
>  for (i = 0; i < type11.nvalues; i++) {
>  SMBIOS_TABLE_SET_STR_LIST(11, type11.values[i]);
> +g_free(type11.values[i]);
> +type11.values[i] = NULL;
>  }
>  
>  SMBIOS_BUILD_TABLE_POST;
> @@ -940,9 +947,8 @@ static void save_opt(const char **dest, QemuOpts *opts, 
> const char *name)
>  
>  
>  struct opt_list {
> -const char *name;
>  size_t *ndest;
> -const char ***dest;
> +char ***dest;
>  };
>  
>  static int save_opt_one(void *opaque,
> @@ -951,23 +957,61 @@ static int save_opt_one(void *opaque,
>  {
>  struct opt_list *opt = opaque;
>  
> -if (!g_str_equal(name, opt->name)) {
> -return 0;
> +if (g_str_equal(name, "path")) {
> +g_autoptr(GByteArray) data = g_byte_array_new();
> +g_autofree char *buf = g_new(char, 4096);
> +ssize_t ret;
> +int fd = qemu_open(value, O_RDONLY);

This line now fails to compile, due to commit c490af57cb45 ("util:
introduce qemu_open and qemu_create with error reporting", 2020-09-16).

... I guess I could test the patch with qemu_open_old(), but that
wouldn't allow for a valid Tested-by.

Thanks,
Laszlo

> +if (fd < 0) {
> +error_setg(errp, "Unable to open %s: %s", value, 
> strerror(errno));
> +return -1;
> +}
> +
> +while (1) {
> +ret = read(fd, buf, 4096);
> +if (ret == 0) {
> +break;
> +}
> +if (ret < 0) {
> +error_setg(errp, "Unable to read from %s: %s",
> +   value, strerror(errno));
> +return -1;
> +}
> +if (memchr(buf, '\0', ret)) {
> +error_setg(errp, "NUL in OEM strings value in %s", value);
> +return -1;
> +}
> +g_byte_array_append(data, (guint8 *)buf, ret);
> +}
> +
> +close(fd);
> +
> +*opt->dest = g_renew(char *, *opt->dest, (*opt->ndest) + 1);
> +(*opt->dest)[*opt->ndest] = (char *)g_byte_array_free(data,  FALSE);
> +(*opt->ndest)++;
> +data = NULL;
> +   } else if (g_str_equal(name, "value")) {
> +*opt->dest = g_renew(char *, *opt->dest, (*opt->ndest) + 1);
> +(*opt->dest)[*opt->ndest] = g_strdup(value);
> +(*opt->ndest)++;
> +} else if (!g_str_equal(name, "type")) {
> +error_setg(errp, "Unexpected option %s", name);
> +return -1;
>  }
>  
> -*opt->dest = g_renew(const char *, *opt->dest, (*opt->ndest) + 1);
> -(*opt->dest)[*opt->ndest] = value;
> -(*opt->ndest)++;
>  return 0;
>  }
>  
> -static void save_opt_list(size_t *ndest, const char ***dest,
> -  QemuOpts *opts, const char *name)
> +static bool save_opt_list(size_t *ndest, char ***dest, QemuOpts *opts,
> +  Error **errp)
>  {
>  struct opt_list opt = {
> -name, ndest, dest,
> +ndest, dest,
>  };
> -qemu_opt_foreach(opts, save_opt_one, , NULL);
> +if (!qemu_opt_foreach(opts, save_opt_one, , errp)) {
> +return false;
> +}
> +return true;
>  }
>  
>  void smbios_entry_add(QemuOpts *opts, Error **errp)
> @@ -1149,7 +1193,9 @@ void 

Re: [PATCH] iotests: Remove 030 from the auto group

2020-09-23 Thread Thomas Huth
On 23/09/2020 20.18, Alberto Garcia wrote:
> On Fri 04 Sep 2020 10:25:13 AM CEST, Kevin Wolf wrote:
>>> Test 030 is still occasionally failing in the CI ... so for the
>>> time being, let's disable it in the "auto" group. We can add it
>>> back once it got more stable.
>>>
>>> Signed-off-by: Thomas Huth 
>>
>> I would rather just disable this one test function as 030 is a pretty
>> important one that tends to catch bugs.
>>
>>>  I just saw the problem here:
>>>   https://cirrus-ci.com/task/5449330930745344?command=main#L6482
>>>  and Peter hit it a couple of weeks ago:
>>>   https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00136.html
>>
>> I wonder how this can still happen. The test should have more than
>> enough time to complete now. Except if the throttling doesn't work as
>> expected.
>>
>> I can't seem to reproduce this even if I add rather long delays. After
>> 40 seconds, all jobs have moved either by 512k (which is STREAM_CHUNK)
>> or not at all.
> 
> I also don't understand how this can fail... I assume the test is not
> running for that long in the cases when it fails, right?

Hard to say ... the problem only occurs occasionally, and I've never
seen it happen "live", only in the CI logs after the job has failed. I
guess you'd have to print timestamps in the code and then submit a lot
of jobs to the CI systems that are sensitive to this problem (e.g.
Cirrus and Travis) to find out...

 Thomas




RE: [RFC PATCH v3 30/34] Hexagon (target/hexagon) TCG for instructions with multiple definitions

2020-09-23 Thread Taylor Simpson


> > On 8/31/20 4:10 PM, Taylor Simpson wrote:
> > >
> > >
> > >> -Original Message-
> > >> From: Richard Henderson 
> > >> Sent: Monday, August 31, 2020 1:20 PM
> > >> To: Taylor Simpson ; qemu-devel@nongnu.org
> > >> Cc: phi...@redhat.com; laur...@vivier.eu; riku.voi...@iki.fi;
> > >> aleksandar.m.m...@gmail.com; a...@rev.ng
> > >> Subject: Re: [RFC PATCH v3 30/34] Hexagon (target/hexagon) TCG for
> > >> instructions with multiple definitions
> > >>
> > Ho hum.  Maybe I'm trying to overthink this too much before tackling the
> > ultimate goal of full parsing of the SHORTCODE.
> > Perhaps the only thing for the short term is to have the generator grep
> > genptr.c for "#define fGEN", to choose between the two alternatives:
> inline
> > generation or out-of-line helper generation.
>
> That's certainly doable.  It will also be good to implement some of your other
> ideas
> - Have the generator expand the DECL/READ/WRITE/FREE macros will make
> the generated code more readable and we can specialize them for
> predicated vs non-predicated instructions which will make translation faster.
> - Generate the entire generate_ function instead of just the body will
> make the generated code more readable.

I've made these changes to the generator.  I hope you like the results.  As an 
example, here is what we generate for the add instruction

DEF_TCG_FUNC(A2_add,
static void generate_A2_add(
CPUHexagonState *env,
DisasContext *ctx,
insn_t *insn,
packet_t *pkt)
{
TCGv RdV = tcg_temp_local_new();
const int RdN = insn->regno[0];
TCGv RsV = hex_gpr[insn->regno[1]];
TCGv RtV = hex_gpr[insn->regno[2]];
gen_helper_A2_add(RdV, cpu_env, RsV, RtV);
gen_log_reg_write(RdN, RdV);
ctx_log_reg_write(ctx, RdN);
tcg_temp_free(RdV);
})

And here is how the generated file gets used in genptr.c

#define DEF_TCG_FUNC(TAG, GENFN) \
GENFN
#include "tcg_funcs_generated.h"
#undef DEF_TCG_FUNC

/*
 * Not all opcodes have generate_ functions, so initialize
 * the table from the tcg_funcs_generated.h file.
 */
const semantic_insn_t opcode_genptr[XX_LAST_OPCODE] = {
#define DEF_TCG_FUNC(TAG, GENFN) \
[TAG] = generate_##TAG,
#include "tcg_funcs_generated.h"
#undef DEF_TCG_FUNC
};

I've also addressed several of the items from Richard's review, so I'll 
resubmit the series once I figure out how to get "make check-tcg" working under 
meson.

Thanks,
Taylor



RE: [RFC PATCH v3 34/34] Hexagon build infrastructure

2020-09-23 Thread Taylor Simpson


> -Original Message-
> From: Richard Henderson 
> Sent: Friday, August 28, 2020 9:20 PM
> To: Taylor Simpson ; qemu-devel@nongnu.org
> Cc: phi...@redhat.com; laur...@vivier.eu; riku.voi...@iki.fi;
> aleksandar.m.m...@gmail.com; a...@rev.ng
> Subject: Re: [RFC PATCH v3 34/34] Hexagon build infrastructure
>
> This will have to be updated for the meson conversion.
>
> I don't understand it all myself, and all of those generated files will need
> special attention.
>

I've made the changes for meson, including converting 
target/hexagon/Makefile.objs to target/hexagon/meson.build, and I can build 
qemu-hexagon with
mkdir build
cd build
configure --target-list=hexagon-linux-user
make

However, when I run "make check-tcg", nothing actually happens.
  BUILD   TCG tests for hexagon-linux-user
Generating qemu-version.h with a meson_exe.py custom command
  RUN TCG tests for hexagon-linux-user

What am I missing?  Has some other command replaced "make check-tcg"?

Thanks,
Taylor




Re: [PATCH 3/4] net/colo-compare.c: Add secondary old packet detection

2020-09-23 Thread Li Zhijian




On 9/23/20 2:47 PM, Zhang, Chen wrote:



-Original Message-
From: Li Zhijian 
Sent: Tuesday, September 22, 2020 2:47 PM
To: Zhang, Chen ; Jason Wang
; qemu-dev 
Cc: Zhang Chen 
Subject: Re: [PATCH 3/4] net/colo-compare.c: Add secondary old packet
detection



On 9/18/20 5:22 PM, Zhang Chen wrote:

From: Zhang Chen 

Detect queued secondary packet to sync VM state in time.

Signed-off-by: Zhang Chen 
---
   net/colo-compare.c | 25 -
   1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c index
3b72309d08..f7271b976f 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -641,19 +641,26 @@ void colo_compare_unregister_notifier(Notifier

*notify)

   static int colo_old_packet_check_one_conn(Connection *conn,
 CompareState *s)
   {
-GList *result = NULL;
-
-result = g_queue_find_custom(>primary_list,
- >compare_timeout,
- (GCompareFunc)colo_old_packet_check_one);
+if (!g_queue_is_empty(>primary_list)) {

Looks we don't need to check is_empty

Re-checked glib code, it just checked the queue rather than inside content.
Maybe check empty before that will benefit performance.

Yeah,  you are right

Reviewed-by: Li Zhijian 

Thank




Thanks
Zhang Chen


+if (g_queue_find_custom(>primary_list,
+>compare_timeout,
+(GCompareFunc)colo_old_packet_check_one))
+goto out;
+}

-if (result) {
-/* Do checkpoint will flush old packet */
-colo_compare_inconsistency_notify(s);
-return 0;
+if (!g_queue_is_empty(>secondary_list)) {

Ditto

Thanks

+if (g_queue_find_custom(>secondary_list,
+>compare_timeout,
+(GCompareFunc)colo_old_packet_check_one))
+goto out;
   }

   return 1;
+
+out:
+/* Do checkpoint will flush old packet */
+colo_compare_inconsistency_notify(s);
+return 0;
   }

   /*












[Bug 1896317] Re: ioapic: UndefinedBehaviorSanitizer starting qemu-system-i386

2020-09-23 Thread Peter Xu
I cannot reproduce locally with 053a4177817...  What could I have
missed?

It's kind of odd - For i386, ioapic_as should be set in
../softmmu/vl.c:4355 in pc_memory_init().

The failure triggered at qemu_init softmmu/vl.c:4458:5, which is later.

However I don't see any place that ioapic_as can be cleared, yet.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1896317

Title:
  ioapic: UndefinedBehaviorSanitizer starting qemu-system-i386

Status in QEMU:
  New

Bug description:
  As of commit 053a4177817:

  $ ./configure --enable-sanitizers --disable-kvm

  $ make qemu-system-i386

  $ ./build/i386-softmmu/qemu-system-i386
  include/exec/memory.h:688:12: runtime error: member access within null 
pointer of type 'AddressSpace' (aka 'struct AddressSpace')
  SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 
include/exec/memory.h:688:12 in 
  AddressSanitizer:DEADLYSIGNAL
  =
  ==249513==ERROR: AddressSanitizer: SEGV on unknown address 0x0020 (pc 
0x55955d7f8c4f bp 0x7fff10f3cff0 sp 0x7fff10f3cf20 T0)
  ==249513==The signal is caused by a READ memory access.
  ==249513==Hint: address points to the zero page.
  #0 0x55955d7f8c4f in address_space_to_flatview 
include/exec/memory.h:688:12
  #1 0x55955d8003d2 in address_space_translate include/exec/memory.h:2286:31
  #2 0x55955d8315f3 in address_space_stl_internal memory_ldst.c.inc:312:10
  #3 0x55955d831cd1 in address_space_stl_le memory_ldst.c.inc:353:5
  #4 0x55955d7ef2e1 in stl_le_phys include/exec/memory_ldst_phys.h.inc:103:5
  #5 0x55955d7ed299 in ioapic_service hw/intc/ioapic.c:138:17
  #6 0x55955d7f0e30 in ioapic_set_irq hw/intc/ioapic.c:186:17
  #7 0x55955e34b825 in qemu_set_irq hw/core/irq.c:45:5
  #8 0x55955d0409e6 in gsi_handler hw/i386/x86.c:583:5
  #9 0x55955e34b825 in qemu_set_irq hw/core/irq.c:45:5
  #10 0x55955ca539c9 in hpet_handle_legacy_irq hw/timer/hpet.c:724:13
  #11 0x55955e34b825 in qemu_set_irq hw/core/irq.c:45:5
  #12 0x55955ce7a695 in pit_irq_timer_update hw/timer/i8254.c:264:5
  #13 0x55955ce7a1d8 in pit_irq_control hw/timer/i8254.c:306:9
  #14 0x55955e34b825 in qemu_set_irq hw/core/irq.c:45:5
  #15 0x55955ca52276 in hpet_reset hw/timer/hpet.c:707:5
  #16 0x55955e342e91 in device_transitional_reset hw/core/qdev.c:1114:9
  #17 0x55955e345cfc in resettable_phase_hold hw/core/resettable.c:182:13
  #18 0x55955e31c1e5 in bus_reset_child_foreach hw/core/bus.c:94:9
  #19 0x55955e348a58 in resettable_child_foreach hw/core/resettable.c:96:9
  #20 0x55955e34596f in resettable_phase_hold hw/core/resettable.c:173:5
  #21 0x55955e344a72 in resettable_assert_reset hw/core/resettable.c:60:5
  #22 0x55955e344919 in resettable_reset hw/core/resettable.c:45:5
  #23 0x55955e3473e9 in resettable_cold_reset_fn hw/core/resettable.c:269:5
  #24 0x55955e344898 in qemu_devices_reset hw/core/reset.c:69:9
  #25 0x55955d05c5b0 in pc_machine_reset hw/i386/pc.c:1632:5
  #26 0x55955d55ab84 in qemu_system_reset softmmu/vl.c:1403:9
  #27 0x55955d56816d in qemu_init softmmu/vl.c:4458:5
  #28 0x55955bc13609 in main softmmu/main.c:49:5
  #29 0x7f3baad20041 in __libc_start_main (/lib64/libc.so.6+0x27041)
  #30 0x55955bb398ed in _start (build-sanitizer/qemu-system-i386+0x1b3d8ed)

  AddressSanitizer can not provide additional info.
  SUMMARY: AddressSanitizer: SEGV include/exec/memory.h:688:12 in 
address_space_to_flatview

  Comment and stl_le_phys() added in commit cb135f59b80:
  /* No matter whether IR is enabled, we translate
   * the IOAPIC message into a MSI one, and its
   * address space will decide whether we need a
   * translation. */
  stl_le_phys(ioapic_as, info.addr, info.data);

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1896317/+subscriptions



Re: [PATCH v2 25/38] qapi/gen.py: add type hint annotations

2020-09-23 Thread Eduardo Habkost
On Wed, Sep 23, 2020 at 08:29:17PM -0400, John Snow wrote:
> On 9/23/20 7:51 PM, Cleber Rosa wrote:
> > On Tue, Sep 22, 2020 at 05:00:48PM -0400, John Snow wrote:
> > > Annotations do not change runtime behavior.
> > > This commit *only* adds annotations.
> > > 
> > > Signed-off-by: John Snow 
> > > ---
> > >   scripts/qapi/gen.py | 102 +++-
> > >   1 file changed, 53 insertions(+), 49 deletions(-)
> > > 
> > > diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
> > > index cb2b2655c3..df8cf8271c 100644
> > > --- a/scripts/qapi/gen.py
> > > +++ b/scripts/qapi/gen.py
> > > @@ -17,7 +17,7 @@
> > >   import errno
> > >   import os
> > >   import re
> > > -from typing import Optional
> > > +from typing import Dict, Generator, List, Optional, Tuple
> > >   from .common import (
> > >   c_fname,
> > > @@ -32,31 +32,31 @@
> > >   QAPISchemaObjectType,
> > >   QAPISchemaVisitor,
> > >   )
> > > +from .source import QAPISourceInfo
> > >   class QAPIGen:
> > > -
> > > -def __init__(self, fname):
> > > +def __init__(self, fname: Optional[str]):
> > >   self.fname = fname
> > >   self._preamble = ''
> > >   self._body = ''
> > > -def preamble_add(self, text):
> > > +def preamble_add(self, text: str) -> None:
> > >   self._preamble += text
> > > -def add(self, text):
> > > +def add(self, text: str) -> None:
> > >   self._body += text
> > > -def get_content(self):
> > > +def get_content(self) -> str:
> > >   return self._top() + self._preamble + self._body + 
> > > self._bottom()
> > > -def _top(self):
> > > +def _top(self) -> str:
> > >   return ''
> > > -def _bottom(self):
> > > +def _bottom(self) -> str:
> > >   return ''
> > > -def write(self, output_dir):
> > > +def write(self, output_dir: str) -> None:
> > >   # Include paths starting with ../ are used to reuse modules of 
> > > the main
> > >   # schema in specialised schemas. Don't overwrite the files that 
> > > are
> > >   # already generated for the main schema.
> > > @@ -81,7 +81,7 @@ def write(self, output_dir):
> > >   f.close()
> > > -def _wrap_ifcond(ifcond, before, after):
> > > +def _wrap_ifcond(ifcond: List[str], before: str, after: str) -> str:
> > >   if before == after:
> > >   return after   # suppress empty #if ... #endif
> > > @@ -121,40 +121,38 @@ def build_params(arg_type: 
> > > Optional[QAPISchemaObjectType],
> > >   class QAPIGenCCode(QAPIGen):
> > > -
> > > -def __init__(self, fname):
> > > +def __init__(self, fname: Optional[str]):
> > >   super().__init__(fname)
> > > -self._start_if = None
> > > +self._start_if: Optional[Tuple[List[str], str, str]] = None
> > > -def start_if(self, ifcond):
> > > +def start_if(self, ifcond: List[str]) -> None:
> > >   assert self._start_if is None
> > >   self._start_if = (ifcond, self._body, self._preamble)
> > > -def end_if(self):
> > > +def end_if(self) -> None:
> > >   assert self._start_if
> > >   self._wrap_ifcond()
> > >   self._start_if = None
> > > -def _wrap_ifcond(self):
> > > +def _wrap_ifcond(self) -> None:
> > >   self._body = _wrap_ifcond(self._start_if[0],
> > > self._start_if[1], self._body)
> > >   self._preamble = _wrap_ifcond(self._start_if[0],
> > > self._start_if[2], self._preamble)
> > > -def get_content(self):
> > > +def get_content(self) -> str:
> > >   assert self._start_if is None
> > >   return super().get_content()
> > >   class QAPIGenC(QAPIGenCCode):
> > > -
> > > -def __init__(self, fname, blurb, pydoc):
> > > +def __init__(self, fname: str, blurb: str, pydoc: str):
> > >   super().__init__(fname)
> > >   self._blurb = blurb
> > >   self._copyright = '\n * '.join(re.findall(r'^Copyright .*', 
> > > pydoc,
> > > re.MULTILINE))
> > > -def _top(self):
> > > +def _top(self) -> str:
> > >   return mcgen('''
> > >   /* AUTOMATICALLY GENERATED, DO NOT MODIFY */
> > > @@ -170,7 +168,7 @@ def _top(self):
> > >   ''',
> > >blurb=self._blurb, copyright=self._copyright)
> > > -def _bottom(self):
> > > +def _bottom(self) -> str:
> > >   return mcgen('''
> > >   /* Dummy declaration to prevent empty .o file */
> > > @@ -180,16 +178,16 @@ def _bottom(self):
> > >   class QAPIGenH(QAPIGenC):
> > > -
> > > -def _top(self):
> > > +def _top(self) -> str:
> > >   return super()._top() + guardstart(self.fname)
> > > -def _bottom(self):
> > > +def _bottom(self) -> str:
> > >   return guardend(self.fname)
> > >   @contextmanager
> > > -def ifcontext(ifcond, *args):
> > > +def ifcontext(ifcond: 

Re: [PATCH v3 51/81] target/arm: Pass separate addend to {U, S}DOT helpers

2020-09-23 Thread LIU Zhiwei



On 2020/9/23 22:46, Richard Henderson wrote:

On 9/23/20 3:01 AM, LIU Zhiwei wrote:


On 2020/9/19 2:37, Richard Henderson wrote:

For SVE, we potentially have a 4th argument coming from the
movprfx instruction.  Currently we do not optimize movprfx,
so the problem is not visible.

Hi Richard,

I am a little confused.  If it is not immediately preceded by a MOVPRFX
instruction, the addend will
still be used.

Is it right?

If movprfx is not used, then the addend register will be the same as the
destination register.

Get it.

Could you see again the definition of HELPER(gvec_udot_idx_h) or the 
HELPER(gvec_sdot_idx_h)?


I think it is wrong there, it code sequence is like this:

d0 = a[i+0]
//dot calculation
d[i+0] += d0

Because when addend is the destination register, it has no reason to add 
destination register twice.


Best Regards,
Zhiwei


r~




[PATCH 7/8] softfloat: Use x86_64 assembly for {add,sub}{192,256}

2020-09-23 Thread Richard Henderson
The compiler cannot chain more than two additions together.
Use inline assembly for 3 or 4 additions.

Signed-off-by: Richard Henderson 
---
 include/fpu/softfloat-macros.h | 18 --
 fpu/softfloat.c| 28 
 2 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h
index 95d88d05b8..99fa124e56 100644
--- a/include/fpu/softfloat-macros.h
+++ b/include/fpu/softfloat-macros.h
@@ -436,6 +436,13 @@ static inline void
  uint64_t *z2Ptr
  )
 {
+#ifdef __x86_64__
+asm("add %5, %2\n\t"
+"adc %4, %1\n\t"
+"adc %3, %0"
+: "="(*z0Ptr), "="(*z1Ptr), "="(*z2Ptr)
+: "rm"(b0), "rm"(b1), "rm"(b2), "0"(a0), "1"(a1), "2"(a2));
+#else
 uint64_t z0, z1, z2;
 int8_t carry0, carry1;
 
@@ -450,7 +457,7 @@ static inline void
 *z2Ptr = z2;
 *z1Ptr = z1;
 *z0Ptr = z0;
-
+#endif
 }
 
 /*
@@ -494,6 +501,13 @@ static inline void
  uint64_t *z2Ptr
  )
 {
+#ifdef __x86_64__
+asm("sub %5, %2\n\t"
+"sbb %4, %1\n\t"
+"sbb %3, %0"
+: "="(*z0Ptr), "="(*z1Ptr), "="(*z2Ptr)
+: "rm"(b0), "rm"(b1), "rm"(b2), "0"(a0), "1"(a1), "2"(a2));
+#else
 uint64_t z0, z1, z2;
 int8_t borrow0, borrow1;
 
@@ -508,7 +522,7 @@ static inline void
 *z2Ptr = z2;
 *z1Ptr = z1;
 *z0Ptr = z0;
-
+#endif
 }
 
 /*
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 5b714fbd82..d8e5d90fd7 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -7297,6 +7297,15 @@ static void shift256RightJamming(uint64_t p[4], int 
count)
 /* R = A - B */
 static void sub256(uint64_t r[4], uint64_t a[4], uint64_t b[4])
 {
+#if defined(__x86_64__)
+asm("sub %7, %3\n\t"
+"sbb %6, %2\n\t"
+"sbb %5, %1\n\t"
+"sbb %4, %0"
+: "="(r[0]), "="(r[1]), "="(r[2]), "="(r[3])
+: "rme"(b[0]), "rme"(b[1]), "rme"(b[2]), "rme"(b[3]),
+"0"(a[0]),   "1"(a[1]),   "2"(a[2]),   "3"(a[3]));
+#else
 bool borrow = false;
 
 for (int i = 3; i >= 0; --i) {
@@ -7308,11 +7317,20 @@ static void sub256(uint64_t r[4], uint64_t a[4], 
uint64_t b[4])
 r[i] = a[i] - b[i];
 }
 }
+#endif
 }
 
 /* A = -A */
 static void neg256(uint64_t a[4])
 {
+#if defined(__x86_64__)
+asm("negq %3\n\t"
+"sbb %6, %2\n\t"
+"sbb %5, %1\n\t"
+"sbb %4, %0"
+: "="(a[0]), "="(a[1]), "="(a[2]), "+rm"(a[3])
+: "rme"(a[0]), "rme"(a[1]), "rme"(a[2]), "0"(0), "1"(0), "2"(0));
+#else
 a[3] = -a[3];
 if (likely(a[3])) {
 goto not2;
@@ -7333,11 +7351,20 @@ static void neg256(uint64_t a[4])
 a[1] = ~a[1];
  not0:
 a[0] = ~a[0];
+#endif
 }
 
 /* A += B */
 static void add256(uint64_t a[4], uint64_t b[4])
 {
+#if defined(__x86_64__)
+asm("add %7, %3\n\t"
+"adc %6, %2\n\t"
+"adc %5, %1\n\t"
+"adc %4, %0"
+:  "+r"(a[0]),  "+r"(a[1]),  "+r"(a[2]),  "+r"(a[3])
+: "rme"(b[0]), "rme"(b[1]), "rme"(b[2]), "rme"(b[3]));
+#else
 bool carry = false;
 
 for (int i = 3; i >= 0; --i) {
@@ -7350,6 +7377,7 @@ static void add256(uint64_t a[4], uint64_t b[4])
 }
 a[i] = t;
 }
+#endif
 }
 
 float128 float128_muladd(float128 a_f, float128 b_f, float128 c_f,
-- 
2.25.1




[PATCH 6/8] softfloat: Implement float128_muladd

2020-09-23 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 include/fpu/softfloat.h |   2 +
 fpu/softfloat.c | 356 +++-
 tests/fp/fp-test.c  |   2 +-
 tests/fp/wrap.c.inc |  12 ++
 4 files changed, 370 insertions(+), 2 deletions(-)

diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 78ad5ca738..a38433deb4 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -1196,6 +1196,8 @@ float128 float128_sub(float128, float128, float_status 
*status);
 float128 float128_mul(float128, float128, float_status *status);
 float128 float128_div(float128, float128, float_status *status);
 float128 float128_rem(float128, float128, float_status *status);
+float128 float128_muladd(float128, float128, float128, int,
+ float_status *status);
 float128 float128_sqrt(float128, float_status *status);
 FloatRelation float128_compare(float128, float128, float_status *status);
 FloatRelation float128_compare_quiet(float128, float128, float_status *status);
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index e038434a07..5b714fbd82 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -512,11 +512,19 @@ static inline __attribute__((unused)) bool 
is_qnan(FloatClass c)
 
 typedef struct {
 uint64_t frac;
-int32_t  exp;
+int32_t exp;
 FloatClass cls;
 bool sign;
 } FloatParts;
 
+/* Similar for float128.  */
+typedef struct {
+uint64_t frac0, frac1;
+int32_t exp;
+FloatClass cls;
+bool sign;
+} FloatParts128;
+
 #define DECOMPOSED_BINARY_POINT(64 - 2)
 #define DECOMPOSED_IMPLICIT_BIT(1ull << DECOMPOSED_BINARY_POINT)
 #define DECOMPOSED_OVERFLOW_BIT(DECOMPOSED_IMPLICIT_BIT << 1)
@@ -4574,6 +4582,46 @@ static void
 
 }
 
+/*
+| Returns the parts of floating-point value `a'.
+**/
+
+static void float128_unpack(FloatParts128 *p, float128 a, float_status *status)
+{
+p->sign = extractFloat128Sign(a);
+p->exp = extractFloat128Exp(a);
+p->frac0 = extractFloat128Frac0(a);
+p->frac1 = extractFloat128Frac1(a);
+
+if (p->exp == 0) {
+if ((p->frac0 | p->frac1) == 0) {
+p->cls = float_class_zero;
+} else if (status->flush_inputs_to_zero) {
+float_raise(float_flag_input_denormal, status);
+p->cls = float_class_zero;
+p->frac0 = p->frac1 = 0;
+} else {
+normalizeFloat128Subnormal(p->frac0, p->frac1, >exp,
+   >frac0, >frac1);
+p->exp -= 0x3fff;
+p->cls = float_class_normal;
+}
+} else if (p->exp == 0x7fff) {
+if ((p->frac0 | p->frac1) == 0) {
+p->cls = float_class_inf;
+} else if (float128_is_signaling_nan(a, status)) {
+p->cls = float_class_snan;
+} else {
+p->cls = float_class_qnan;
+}
+} else {
+/* Add the implicit bit. */
+p->frac0 |= UINT64_C(0x0001);
+p->exp -= 0x3fff;
+p->cls = float_class_normal;
+}
+}
+
 /*
 | Packs the sign `zSign', the exponent `zExp', and the significand formed
 | by the concatenation of `zSig0' and `zSig1' into a quadruple-precision
@@ -7205,6 +7253,312 @@ float128 float128_mul(float128 a, float128 b, 
float_status *status)
 
 }
 
+static void shortShift256Left(uint64_t p[4], unsigned count)
+{
+int negcount = -count & 63;
+
+if (count == 0) {
+return;
+}
+g_assert(count < 64);
+p[0] = (p[0] << count) | (p[1] >> negcount);
+p[1] = (p[1] << count) | (p[2] >> negcount);
+p[2] = (p[2] << count) | (p[3] >> negcount);
+p[3] = (p[3] << count);
+}
+
+static void shift256RightJamming(uint64_t p[4], int count)
+{
+uint64_t in = 0;
+
+g_assert(count >= 0);
+
+count = MIN(count, 256);
+for (; count >= 64; count -= 64) {
+in |= p[3];
+p[3] = p[2];
+p[2] = p[1];
+p[1] = p[0];
+p[0] = 0;
+}
+
+if (count) {
+int negcount = -count & 63;
+
+in |= p[3] << negcount;
+p[3] = (p[2] << negcount) | (p[3] >> count);
+p[2] = (p[1] << negcount) | (p[2] >> count);
+p[1] = (p[0] << negcount) | (p[1] >> count);
+p[0] = p[0] >> count;
+}
+p[3] |= (in != 0);
+}
+
+/* R = A - B */
+static void sub256(uint64_t r[4], uint64_t a[4], uint64_t b[4])
+{
+bool borrow = false;
+
+for (int i = 3; i >= 0; --i) {
+if (borrow) {
+borrow = a[i] <= b[i];
+r[i] = a[i] - b[i] - 1;
+} else {
+borrow = a[i] < b[i];
+r[i] = a[i] - b[i];
+}
+}
+}
+
+/* A = -A */
+static void neg256(uint64_t a[4])
+{
+a[3] = -a[3];
+if (likely(a[3])) {
+goto not2;
+}
+a[2] = 

[PATCH 8/8] softfloat: Use aarch64 assembly for {add,sub}{192,256}

2020-09-23 Thread Richard Henderson
The compiler cannot chain more than two additions together.
Use inline assembly for 3 or 4 additions.

Signed-off-by: Richard Henderson 
---
 include/fpu/softfloat-macros.h | 14 ++
 fpu/softfloat.c| 25 +
 2 files changed, 39 insertions(+)

diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h
index 99fa124e56..969a486fd2 100644
--- a/include/fpu/softfloat-macros.h
+++ b/include/fpu/softfloat-macros.h
@@ -442,6 +442,13 @@ static inline void
 "adc %3, %0"
 : "="(*z0Ptr), "="(*z1Ptr), "="(*z2Ptr)
 : "rm"(b0), "rm"(b1), "rm"(b2), "0"(a0), "1"(a1), "2"(a2));
+#elif defined(__aarch64__)
+asm("adds %2, %x5, %x8\n\t"
+"adcs %1, %x4, %x7\n\t"
+"adc  %0, %x3, %x6"
+: "="(*z0Ptr), "="(*z1Ptr), "="(*z2Ptr)
+: "rZ"(a0), "rZ"(a1), "rZ"(a2), "rZ"(b0), "rZ"(b1), "rZ"(b2)
+: "cc");
 #else
 uint64_t z0, z1, z2;
 int8_t carry0, carry1;
@@ -507,6 +514,13 @@ static inline void
 "sbb %3, %0"
 : "="(*z0Ptr), "="(*z1Ptr), "="(*z2Ptr)
 : "rm"(b0), "rm"(b1), "rm"(b2), "0"(a0), "1"(a1), "2"(a2));
+#elif defined(__aarch64__)
+asm("subs %2, %x5, %x8\n\t"
+"sbcs %1, %x4, %x7\n\t"
+"sbc  %0, %x3, %x6"
+: "="(*z0Ptr), "="(*z1Ptr), "="(*z2Ptr)
+: "rZ"(a0), "rZ"(a1), "rZ"(a2), "rZ"(b0), "rZ"(b1), "rZ"(b2)
+: "cc");
 #else
 uint64_t z0, z1, z2;
 int8_t borrow0, borrow1;
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index d8e5d90fd7..1601095d60 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -7305,6 +7305,16 @@ static void sub256(uint64_t r[4], uint64_t a[4], 
uint64_t b[4])
 : "="(r[0]), "="(r[1]), "="(r[2]), "="(r[3])
 : "rme"(b[0]), "rme"(b[1]), "rme"(b[2]), "rme"(b[3]),
 "0"(a[0]),   "1"(a[1]),   "2"(a[2]),   "3"(a[3]));
+#elif defined(__aarch64__)
+asm("subs %[r3], %x[a3], %x[b3]\n\t"
+"sbcs %[r2], %x[a2], %x[b2]\n\t"
+"sbcs %[r1], %x[a1], %x[b1]\n\t"
+"sbc  %[r0], %x[a0], %x[b0]"
+: [r0] "="(r[0]), [r1] "="(r[1]),
+  [r2] "="(r[2]), [r3] "="(r[3])
+: [a0] "rZ"(a[0]), [a1] "rZ"(a[1]), [a2] "rZ"(a[2]), [a3] "rZ"(a[3]),
+  [b0] "rZ"(b[0]), [b1] "rZ"(b[1]), [b2] "rZ"(b[2]), [b3] "rZ"(b[3])
+: "cc");
 #else
 bool borrow = false;
 
@@ -7330,6 +7340,13 @@ static void neg256(uint64_t a[4])
 "sbb %4, %0"
 : "="(a[0]), "="(a[1]), "="(a[2]), "+rm"(a[3])
 : "rme"(a[0]), "rme"(a[1]), "rme"(a[2]), "0"(0), "1"(0), "2"(0));
+#elif defined(__aarch64__)
+asm("negs %3, %3\n\t"
+"ngcs %2, %2\n\t"
+"ngcs %1, %1\n\t"
+"ngc  %0, %0"
+: "+r"(a[0]), "+r"(a[1]), "+r"(a[2]), "+r"(a[3])
+: : "cc");
 #else
 a[3] = -a[3];
 if (likely(a[3])) {
@@ -7364,6 +7381,14 @@ static void add256(uint64_t a[4], uint64_t b[4])
 "adc %4, %0"
 :  "+r"(a[0]),  "+r"(a[1]),  "+r"(a[2]),  "+r"(a[3])
 : "rme"(b[0]), "rme"(b[1]), "rme"(b[2]), "rme"(b[3]));
+#elif defined(__aarch64__)
+asm("adds %3, %3, %x7\n\t"
+"adcs %2, %2, %x6\n\t"
+"adcs %1, %1, %x5\n\t"
+"adc  %0, %0, %x4"
+: "+r"(a[0]), "+r"(a[1]), "+r"(a[2]), "+r"(a[3])
+: "rZ"(b[0]), "rZ"(b[1]), "rZ"(b[2]), "rZ"(b[3])
+: "cc");
 #else
 bool carry = false;
 
-- 
2.25.1




[PATCH 2/8] softfloat: Use int128.h for some operations

2020-09-23 Thread Richard Henderson
Use our Int128, which wraps the compiler's __int128_t,
instead of open-coding left shifts and arithmetic.
We'd need to extend Int128 to have unsigned operations
to replace more than these three.

Signed-off-by: Richard Henderson 
---
 include/fpu/softfloat-macros.h | 39 +-
 1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h
index 57845f8af0..95d88d05b8 100644
--- a/include/fpu/softfloat-macros.h
+++ b/include/fpu/softfloat-macros.h
@@ -84,6 +84,7 @@ this code that are retained.
 
 #include "fpu/softfloat-types.h"
 #include "qemu/host-utils.h"
+#include "qemu/int128.h"
 
 /*
 | Shifts `a' right by the number of bits given in `count'.  If any nonzero
@@ -352,13 +353,11 @@ static inline void shortShift128Left(uint64_t a0, 
uint64_t a1, int count,
 static inline void shift128Left(uint64_t a0, uint64_t a1, int count,
 uint64_t *z0Ptr, uint64_t *z1Ptr)
 {
-if (count < 64) {
-*z1Ptr = a1 << count;
-*z0Ptr = count == 0 ? a0 : (a0 << count) | (a1 >> (-count & 63));
-} else {
-*z1Ptr = 0;
-*z0Ptr = a1 << (count - 64);
-}
+Int128 a = int128_make128(a1, a0);
+Int128 z = int128_lshift(a, count);
+
+*z0Ptr = int128_gethi(z);
+*z1Ptr = int128_getlo(z);
 }
 
 /*
@@ -405,15 +404,15 @@ static inline void
 **/
 
 static inline void
- add128(
- uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1, uint64_t *z0Ptr, 
uint64_t *z1Ptr )
+add128(uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1,
+   uint64_t *z0Ptr, uint64_t *z1Ptr)
 {
-uint64_t z1;
-
-z1 = a1 + b1;
-*z1Ptr = z1;
-*z0Ptr = a0 + b0 + ( z1 < a1 );
+Int128 a = int128_make128(a1, a0);
+Int128 b = int128_make128(b1, b0);
+Int128 z = int128_add(a, b);
 
+*z0Ptr = int128_gethi(z);
+*z1Ptr = int128_getlo(z);
 }
 
 /*
@@ -463,13 +462,15 @@ static inline void
 **/
 
 static inline void
- sub128(
- uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1, uint64_t *z0Ptr, 
uint64_t *z1Ptr )
+sub128(uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1,
+   uint64_t *z0Ptr, uint64_t *z1Ptr)
 {
+Int128 a = int128_make128(a1, a0);
+Int128 b = int128_make128(b1, b0);
+Int128 z = int128_sub(a, b);
 
-*z1Ptr = a1 - b1;
-*z0Ptr = a0 - b0 - ( a1 < b1 );
-
+*z0Ptr = int128_gethi(z);
+*z1Ptr = int128_getlo(z);
 }
 
 /*
-- 
2.25.1




[PATCH 5/8] softfloat: Inline pick_nan_muladd into its caller

2020-09-23 Thread Richard Henderson
Because of FloatParts, there will only ever be one caller.
Inlining allows us to re-use abc_mask for the snan test.

Signed-off-by: Richard Henderson 
---
 fpu/softfloat.c | 75 +++--
 1 file changed, 35 insertions(+), 40 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 3e625c47cd..e038434a07 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -929,45 +929,6 @@ static FloatParts pick_nan(FloatParts a, FloatParts b, 
float_status *s)
 return a;
 }
 
-static FloatParts pick_nan_muladd(FloatParts a, FloatParts b, FloatParts c,
-  bool inf_zero, float_status *s)
-{
-int which;
-
-if (is_snan(a.cls) || is_snan(b.cls) || is_snan(c.cls)) {
-s->float_exception_flags |= float_flag_invalid;
-}
-
-which = pickNaNMulAdd(a.cls, b.cls, c.cls, inf_zero, s);
-
-if (s->default_nan_mode) {
-/* Note that this check is after pickNaNMulAdd so that function
- * has an opportunity to set the Invalid flag.
- */
-which = 3;
-}
-
-switch (which) {
-case 0:
-break;
-case 1:
-a = b;
-break;
-case 2:
-a = c;
-break;
-case 3:
-return parts_default_nan(s);
-default:
-g_assert_not_reached();
-}
-
-if (is_snan(a.cls)) {
-return parts_silence_nan(a, s);
-}
-return a;
-}
-
 /*
  * Returns the result of adding or subtracting the values of the
  * floating-point values `a' and `b'. The operation is performed
@@ -1366,7 +1327,41 @@ static FloatParts muladd_floats(FloatParts a, FloatParts 
b, FloatParts c,
  * off to the target-specific pick-a-NaN routine.
  */
 if (unlikely(abc_mask & float_cmask_anynan)) {
-return pick_nan_muladd(a, b, c, inf_zero, s);
+int which;
+
+if (unlikely(abc_mask & float_cmask_snan)) {
+float_raise(float_flag_invalid, s);
+}
+
+which = pickNaNMulAdd(a.cls, b.cls, c.cls, inf_zero, s);
+
+if (s->default_nan_mode) {
+/*
+ * Note that this check is after pickNaNMulAdd so that function
+ * has an opportunity to set the Invalid flag for inf_zero.
+ */
+which = 3;
+}
+
+switch (which) {
+case 0:
+break;
+case 1:
+a = b;
+break;
+case 2:
+a = c;
+break;
+case 3:
+return parts_default_nan(s);
+default:
+g_assert_not_reached();
+}
+
+if (is_snan(a.cls)) {
+return parts_silence_nan(a, s);
+}
+return a;
 }
 
 if (unlikely(inf_zero)) {
-- 
2.25.1




[PATCH 1/8] softfloat: Use mulu64 for mul64To128

2020-09-23 Thread Richard Henderson
Via host-utils.h, we use a host widening multiply for
64-bit hosts, and a common subroutine for 32-bit hosts.

Signed-off-by: Richard Henderson 
---
 include/fpu/softfloat-macros.h | 24 
 1 file changed, 4 insertions(+), 20 deletions(-)

diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h
index a35ec2893a..57845f8af0 100644
--- a/include/fpu/softfloat-macros.h
+++ b/include/fpu/softfloat-macros.h
@@ -83,6 +83,7 @@ this code that are retained.
 #define FPU_SOFTFLOAT_MACROS_H
 
 #include "fpu/softfloat-types.h"
+#include "qemu/host-utils.h"
 
 /*
 | Shifts `a' right by the number of bits given in `count'.  If any nonzero
@@ -515,27 +516,10 @@ static inline void
 | `z0Ptr' and `z1Ptr'.
 **/
 
-static inline void mul64To128( uint64_t a, uint64_t b, uint64_t *z0Ptr, 
uint64_t *z1Ptr )
+static inline void
+mul64To128(uint64_t a, uint64_t b, uint64_t *z0Ptr, uint64_t *z1Ptr)
 {
-uint32_t aHigh, aLow, bHigh, bLow;
-uint64_t z0, zMiddleA, zMiddleB, z1;
-
-aLow = a;
-aHigh = a>>32;
-bLow = b;
-bHigh = b>>32;
-z1 = ( (uint64_t) aLow ) * bLow;
-zMiddleA = ( (uint64_t) aLow ) * bHigh;
-zMiddleB = ( (uint64_t) aHigh ) * bLow;
-z0 = ( (uint64_t) aHigh ) * bHigh;
-zMiddleA += zMiddleB;
-z0 += ( ( (uint64_t) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 );
-zMiddleA <<= 32;
-z1 += zMiddleA;
-z0 += ( z1 < zMiddleA );
-*z1Ptr = z1;
-*z0Ptr = z0;
-
+mulu64(z1Ptr, z0Ptr, a, b);
 }
 
 /*
-- 
2.25.1




[PATCH 3/8] softfloat: Tidy a * b + inf return

2020-09-23 Thread Richard Henderson
No reason to set values in 'a', when we already
have float_class_inf in 'c', and can flip that sign.

Signed-off-by: Richard Henderson 
---
 fpu/softfloat.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 67cfa0fd82..9db55d2b11 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1380,9 +1380,8 @@ static FloatParts muladd_floats(FloatParts a, FloatParts 
b, FloatParts c,
 s->float_exception_flags |= float_flag_invalid;
 return parts_default_nan(s);
 } else {
-a.cls = float_class_inf;
-a.sign = c.sign ^ sign_flip;
-return a;
+c.sign ^= sign_flip;
+return c;
 }
 }
 
-- 
2.25.1




[PATCH 0/8] softfloat: Implement float128_muladd

2020-09-23 Thread Richard Henderson
Plus assorted cleanups, passes tests/fp/fp-test.
I will eventually fill in ppc and s390x assembly bits.


r~


Richard Henderson (8):
  softfloat: Use mulu64 for mul64To128
  softfloat: Use int128.h for some operations
  softfloat: Tidy a * b + inf return
  softfloat: Add float_cmask and constants
  softfloat: Inline pick_nan_muladd into its caller
  softfloat: Implement float128_muladd
  softfloat: Use x86_64 assembly for {add,sub}{192,256}
  softfloat: Use aarch64 assembly for {add,sub}{192,256}

 include/fpu/softfloat-macros.h |  95 +++---
 include/fpu/softfloat.h|   2 +
 fpu/softfloat.c| 520 +
 tests/fp/fp-test.c |   2 +-
 tests/fp/wrap.c.inc|  12 +
 5 files changed, 538 insertions(+), 93 deletions(-)

-- 
2.25.1




[PATCH 4/8] softfloat: Add float_cmask and constants

2020-09-23 Thread Richard Henderson
Testing more than one class at a time is better done with masks.
This reduces the static branch count.

Signed-off-by: Richard Henderson 
---
 fpu/softfloat.c | 31 ---
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 9db55d2b11..3e625c47cd 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -469,6 +469,20 @@ typedef enum __attribute__ ((__packed__)) {
 float_class_snan,
 } FloatClass;
 
+#define float_cmask(bit)  (1u << (bit))
+
+enum {
+float_cmask_zero= float_cmask(float_class_zero),
+float_cmask_normal  = float_cmask(float_class_normal),
+float_cmask_inf = float_cmask(float_class_inf),
+float_cmask_qnan= float_cmask(float_class_qnan),
+float_cmask_snan= float_cmask(float_class_snan),
+
+float_cmask_infzero = float_cmask_zero | float_cmask_inf,
+float_cmask_anynan  = float_cmask_qnan | float_cmask_snan,
+};
+
+
 /* Simple helpers for checking if, or what kind of, NaN we have */
 static inline __attribute__((unused)) bool is_nan(FloatClass c)
 {
@@ -1335,24 +1349,27 @@ bfloat16 QEMU_FLATTEN bfloat16_mul(bfloat16 a, bfloat16 
b, float_status *status)
 static FloatParts muladd_floats(FloatParts a, FloatParts b, FloatParts c,
 int flags, float_status *s)
 {
-bool inf_zero = ((1 << a.cls) | (1 << b.cls)) ==
-((1 << float_class_inf) | (1 << float_class_zero));
-bool p_sign;
+bool inf_zero, p_sign;
 bool sign_flip = flags & float_muladd_negate_result;
 FloatClass p_class;
 uint64_t hi, lo;
 int p_exp;
+int ab_mask, abc_mask;
+
+ab_mask = float_cmask(a.cls) | float_cmask(b.cls);
+abc_mask = float_cmask(c.cls) | ab_mask;
+inf_zero = ab_mask == float_cmask_infzero;
 
 /* It is implementation-defined whether the cases of (0,inf,qnan)
  * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN
  * they return if they do), so we have to hand this information
  * off to the target-specific pick-a-NaN routine.
  */
-if (is_nan(a.cls) || is_nan(b.cls) || is_nan(c.cls)) {
+if (unlikely(abc_mask & float_cmask_anynan)) {
 return pick_nan_muladd(a, b, c, inf_zero, s);
 }
 
-if (inf_zero) {
+if (unlikely(inf_zero)) {
 s->float_exception_flags |= float_flag_invalid;
 return parts_default_nan(s);
 }
@@ -1367,9 +1384,9 @@ static FloatParts muladd_floats(FloatParts a, FloatParts 
b, FloatParts c,
 p_sign ^= 1;
 }
 
-if (a.cls == float_class_inf || b.cls == float_class_inf) {
+if (ab_mask & float_cmask_inf) {
 p_class = float_class_inf;
-} else if (a.cls == float_class_zero || b.cls == float_class_zero) {
+} else if (ab_mask & float_cmask_zero) {
 p_class = float_class_zero;
 } else {
 p_class = float_class_normal;
-- 
2.25.1




Re: [PATCH v8 4/7] scripts: add block-coroutine-wrapper.py

2020-09-23 Thread Eric Blake

On 9/23/20 7:00 PM, Eric Blake wrote:



Tested-by: Eric Blake 

There's enough grammar fixes, and the fact that John is working on 
python cleanups, to make me wonder if we need a v9, or if I should just 
stage it where it is with any other cleanups as followups.  But I'm 
liking the reduced maintenance burden once it is in, and don't want to 
drag it out to the point that it needs more rebasing as other things 
land first.




Here's what I've squashed in and temporarily pushed to my tree if you 
want to double-check my rebase work:

https://repo.or.cz/qemu/ericb.git/shortlog/refs/heads/master

diff --git a/docs/devel/block-coroutine-wrapper.rst 
b/docs/devel/block-coroutine-wrapper.rst

index f7050bbc8fa6..d09fff2cc539 100644
--- a/docs/devel/block-coroutine-wrapper.rst
+++ b/docs/devel/block-coroutine-wrapper.rst
@@ -2,43 +2,43 @@
 block-coroutine-wrapper
 ===

-A lot of functions in QEMJ block layer (see ``block/*``) can by called
-only in coroutine context. Such functions are normally marked by
+A lot of functions in QEMU block layer (see ``block/*``) can only be
+called in coroutine context. Such functions are normally marked by the
 coroutine_fn specifier. Still, sometimes we need to call them from
-non-coroutine context, for this we need to start a coroutine, run the
+non-coroutine context; for this we need to start a coroutine, run the
 needed function from it and wait for coroutine finish in
 BDRV_POLL_WHILE() loop. To run a coroutine we need a function with one
-void* argument. So for each coroutine_fn function, which needs
+void* argument. So for each coroutine_fn function which needs a
 non-coroutine interface, we should define a structure to pack the
 parameters, define a separate function to unpack the parameters and
 call the original function and finally define a new interface function
 with same list of arguments as original one, which will pack the
 parameters into a struct, create a coroutine, run it and wait in
-BDRV_POLL_WHILE() loop. It's boring to create such wrappers by hand, so
-we have a script to generate them.
+BDRV_POLL_WHILE() loop. It's boring to create such wrappers by hand,
+so we have a script to generate them.

 Usage
 =

-Assume we have defined ``coroutine_fn`` function
+Assume we have defined the ``coroutine_fn`` function
 ``bdrv_co_foo()`` and need a non-coroutine interface for it,
 called ``bdrv_foo()``. In this case the script can help. To
 trigger the generation:

-1. You need ``bdrv_foo`` declaration somewhere (for example in
-   ``block/coroutines.h`` with ``generated_co_wrapper`` mark,
+1. You need ``bdrv_foo`` declaration somewhere (for example, in
+   ``block/coroutines.h``) with the ``generated_co_wrapper`` mark,
like this:

 .. code-block:: c

-int generated_co_wrapper bdrv_foor();
+int generated_co_wrapper bdrv_foo();

 2. You need to feed this declaration to block-coroutine-wrapper script.
-   For this, add .h (or .c) file with the declaration to
+   For this, add the .h (or .c) file with the declaration to the
``input: files(...)`` list of ``block_gen_c`` target declaration in
``block/meson.build``

-You are done. On build, coroutine wrappers will be generated in
+You are done. During the build, coroutine wrappers will be generated in
 ``/block/block-gen.c``.

 Links
diff --git a/docs/devel/index.rst b/docs/devel/index.rst
index 04773ce076b3..cb0abe1e6988 100644
--- a/docs/devel/index.rst
+++ b/docs/devel/index.rst
@@ -31,3 +31,4 @@ Contents:
reset
s390-dasd-ipl
clocks
+   block-coroutine-wrapper
diff --git a/scripts/block-coroutine-wrapper.py 
b/scripts/block-coroutine-wrapper.py

index d859c07a5f55..8c0a08d9b020 100755
--- a/scripts/block-coroutine-wrapper.py
+++ b/scripts/block-coroutine-wrapper.py
@@ -2,7 +2,7 @@
 """Generate coroutine wrappers for block subsystem.

 The program parses one or several concatenated c files from stdin,
-searches for functions with 'generated_co_wrapper' specifier
+searches for functions with the 'generated_co_wrapper' specifier
 and generates corresponding wrappers on stdout.

 Usage: block-coroutine-wrapper.py generated-file.c FILE.[ch]...
@@ -39,7 +39,7 @@ def prettify(code: str) -> str:
 'BraceWrapping': {'AfterFunction': True},
 'BreakBeforeBraces': 'Custom',
 'SortIncludes': False,
-'MaxEmptyLinesToKeep': 2
+'MaxEmptyLinesToKeep': 2,
 })
 p = subprocess.run(['clang-format', f'-style={style}'], 
check=True,

encoding='utf-8', input=code,
@@ -168,7 +168,7 @@ int {func.name}({ func.gen_list('{decl}') })


 def gen_wrappers_file(input_code: str) -> str:
-res = gen_header()
+res = ''
 for func in func_decl_iter(input_code):
 res += '\n\n\n'
 res += gen_wrapper(func)
@@ -181,6 +181,7 @@ if __name__ == '__main__':
 exit(f'Usage: {sys.argv[0]} OUT_FILE.c IN_FILE.[ch]...')

 with open(sys.argv[1], 'w') as f_out:
+

Re: [PATCH v2 25/38] qapi/gen.py: add type hint annotations

2020-09-23 Thread John Snow

On 9/23/20 7:51 PM, Cleber Rosa wrote:

On Tue, Sep 22, 2020 at 05:00:48PM -0400, John Snow wrote:

Annotations do not change runtime behavior.
This commit *only* adds annotations.

Signed-off-by: John Snow 
---
  scripts/qapi/gen.py | 102 +++-
  1 file changed, 53 insertions(+), 49 deletions(-)

diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
index cb2b2655c3..df8cf8271c 100644
--- a/scripts/qapi/gen.py
+++ b/scripts/qapi/gen.py
@@ -17,7 +17,7 @@
  import errno
  import os
  import re
-from typing import Optional
+from typing import Dict, Generator, List, Optional, Tuple
  
  from .common import (

  c_fname,
@@ -32,31 +32,31 @@
  QAPISchemaObjectType,
  QAPISchemaVisitor,
  )
+from .source import QAPISourceInfo
  
  
  class QAPIGen:

-
-def __init__(self, fname):
+def __init__(self, fname: Optional[str]):
  self.fname = fname
  self._preamble = ''
  self._body = ''
  
-def preamble_add(self, text):

+def preamble_add(self, text: str) -> None:
  self._preamble += text
  
-def add(self, text):

+def add(self, text: str) -> None:
  self._body += text
  
-def get_content(self):

+def get_content(self) -> str:
  return self._top() + self._preamble + self._body + self._bottom()
  
-def _top(self):

+def _top(self) -> str:
  return ''
  
-def _bottom(self):

+def _bottom(self) -> str:
  return ''
  
-def write(self, output_dir):

+def write(self, output_dir: str) -> None:
  # Include paths starting with ../ are used to reuse modules of the 
main
  # schema in specialised schemas. Don't overwrite the files that are
  # already generated for the main schema.
@@ -81,7 +81,7 @@ def write(self, output_dir):
  f.close()
  
  
-def _wrap_ifcond(ifcond, before, after):

+def _wrap_ifcond(ifcond: List[str], before: str, after: str) -> str:
  if before == after:
  return after   # suppress empty #if ... #endif
  
@@ -121,40 +121,38 @@ def build_params(arg_type: Optional[QAPISchemaObjectType],
  
  
  class QAPIGenCCode(QAPIGen):

-
-def __init__(self, fname):
+def __init__(self, fname: Optional[str]):
  super().__init__(fname)
-self._start_if = None
+self._start_if: Optional[Tuple[List[str], str, str]] = None
  
-def start_if(self, ifcond):

+def start_if(self, ifcond: List[str]) -> None:
  assert self._start_if is None
  self._start_if = (ifcond, self._body, self._preamble)
  
-def end_if(self):

+def end_if(self) -> None:
  assert self._start_if
  self._wrap_ifcond()
  self._start_if = None
  
-def _wrap_ifcond(self):

+def _wrap_ifcond(self) -> None:
  self._body = _wrap_ifcond(self._start_if[0],
self._start_if[1], self._body)
  self._preamble = _wrap_ifcond(self._start_if[0],
self._start_if[2], self._preamble)
  
-def get_content(self):

+def get_content(self) -> str:
  assert self._start_if is None
  return super().get_content()
  
  
  class QAPIGenC(QAPIGenCCode):

-
-def __init__(self, fname, blurb, pydoc):
+def __init__(self, fname: str, blurb: str, pydoc: str):
  super().__init__(fname)
  self._blurb = blurb
  self._copyright = '\n * '.join(re.findall(r'^Copyright .*', pydoc,
re.MULTILINE))
  
-def _top(self):

+def _top(self) -> str:
  return mcgen('''
  /* AUTOMATICALLY GENERATED, DO NOT MODIFY */
  
@@ -170,7 +168,7 @@ def _top(self):

  ''',
   blurb=self._blurb, copyright=self._copyright)
  
-def _bottom(self):

+def _bottom(self) -> str:
  return mcgen('''
  
  /* Dummy declaration to prevent empty .o file */

@@ -180,16 +178,16 @@ def _bottom(self):
  
  
  class QAPIGenH(QAPIGenC):

-
-def _top(self):
+def _top(self) -> str:
  return super()._top() + guardstart(self.fname)
  
-def _bottom(self):

+def _bottom(self) -> str:
  return guardend(self.fname)
  
  
  @contextmanager

-def ifcontext(ifcond, *args):
+def ifcontext(ifcond: List[str],
+  *args: QAPIGenCCode) -> Generator[None, None, None]:


IIUC, this could simply be "Iterator[None]" instead of
"Generator[None, None, None]".

Anyway,

Reviewed-by: Cleber Rosa 



Oh, you're right! Let's do that instead.

Reference: 
https://mypy.readthedocs.io/en/stable/kinds_of_types.html#generators


Eduardo, I am making this change and keeping your R-B.

--js




Re: [PATCH v8 4/7] scripts: add block-coroutine-wrapper.py

2020-09-23 Thread Eric Blake

On 9/15/20 11:44 AM, Vladimir Sementsov-Ogievskiy wrote:

We have a very frequent pattern of creating coroutine from function
with several arguments:




+++ b/scripts/block-coroutine-wrapper.py
@@ -0,0 +1,187 @@
+#!/usr/bin/env python3
+"""Generate coroutine wrappers for block subsystem.


Looking at the generated file after patch 5 is applied,...



+
+def gen_header():
+copyright = re.sub('^.*Copyright', 'Copyright', __doc__, flags=re.DOTALL)
+copyright = re.sub('^(?=.)', ' * ', copyright.strip(), flags=re.MULTILINE)
+copyright = re.sub('^$', ' *', copyright, flags=re.MULTILINE)
+return f"""\


This generated comment...



+
+
+def gen_wrappers_file(input_code: str) -> str:
+res = gen_header()


...is getting inserted into the generated file...


+for func in func_decl_iter(input_code):
+res += '\n\n\n'
+res += gen_wrapper(func)
+
+return prettify(res)  # prettify to wrap long lines
+
+
+if __name__ == '__main__':
+if len(sys.argv) < 3:
+exit(f'Usage: {sys.argv[0]} OUT_FILE.c IN_FILE.[ch]...')
+
+with open(sys.argv[1], 'w') as f_out:
+for fname in sys.argv[2:]:
+with open(fname) as f_in:
+f_out.write(gen_wrappers_file(f_in.read()))


multiple times.  You'll want to hoist the call to gen_header outside the 
loop over fname in sys.argv[2:].


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v8 4/7] scripts: add block-coroutine-wrapper.py

2020-09-23 Thread Eric Blake

On 9/15/20 3:02 PM, Vladimir Sementsov-Ogievskiy wrote:

15.09.2020 19:44, Vladimir Sementsov-Ogievskiy wrote:

We have a very frequent pattern of creating coroutine from function
with several arguments:

   - create structure to pack parameters
   - create _entry function to call original function taking parameters
 from struct
   - do different magic to handle completion: set ret to NOT_DONE or
 EINPROGRESS or use separate bool field
   - fill the struct and create coroutine from _entry function and this
 struct as a parameter
   - do coroutine enter and BDRV_POLL_WHILE loop

Let's reduce code duplication by generating coroutine wrappers.

This patch adds scripts/block-coroutine-wrapper.py together with some
friends, which will generate functions with declared prototypes marked
by 'generated_co_wrapper' specifier.





 4. add header with generated_co_wrapper declaration into
    COROUTINE_HEADERS list in Makefile


This phrase is out-of-date.  I also see 4 steps here,...



Still, no function is now marked, this work is for the following
commit.

Signed-off-by: Vladimir Sementsov-Ogievskiy
---
  docs/devel/block-coroutine-wrapper.rst |  54 +++
  block/block-gen.h  |  49 +++
  include/block/block.h  |  10 ++
  block/meson.build  |   8 ++
  scripts/block-coroutine-wrapper.py | 187 +
  5 files changed, 308 insertions(+)
  create mode 100644 docs/devel/block-coroutine-wrapper.rst
  create mode 100644 block/block-gen.h
  create mode 100755 scripts/block-coroutine-wrapper.py



Also needed:

diff --git a/docs/devel/index.rst b/docs/devel/index.rst
index 04773ce076..cb0abe1e69 100644
--- a/docs/devel/index.rst
+++ b/docs/devel/index.rst
@@ -31,3 +31,4 @@ Contents:
     reset
     s390-dasd-ipl
     clocks
+   block-coroutine-wrapper


I've squashed that in.


+++ b/docs/devel/block-coroutine-wrapper.rst
@@ -0,0 +1,54 @@
+===
+block-coroutine-wrapper
+===
+
+A lot of functions in QEMJ block layer (see ``block/*``) can by called


QEMU

s/by called only/only be called/


+only in coroutine context. Such functions are normally marked by


by the


+coroutine_fn specifier. Still, sometimes we need to call them from
+non-coroutine context, for this we need to start a coroutine, run the



s/context,/context;/


+needed function from it and wait for coroutine finish in


in a


+BDRV_POLL_WHILE() loop. To run a coroutine we need a function with one
+void* argument. So for each coroutine_fn function, which needs


needs a


+non-coroutine interface, we should define a structure to pack the
+parameters, define a separate function to unpack the parameters and
+call the original function and finally define a new interface function
+with same list of arguments as original one, which will pack the
+parameters into a struct, create a coroutine, run it and wait in
+BDRV_POLL_WHILE() loop. It's boring to create such wrappers by hand, so
+we have a script to generate them.

+Usage
+=
+
+Assume we have defined ``coroutine_fn`` function
+``bdrv_co_foo()`` and need a non-coroutine interface for it,
+called ``bdrv_foo()``. In this case the script can help. To
+trigger the generation:
+
+1. You need ``bdrv_foo`` declaration somewhere (for example in
+   ``block/coroutines.h`` with ``generated_co_wrapper`` mark,
+   like this:


Missing a closing ).


+
+.. code-block:: c
+
+int generated_co_wrapper bdrv_foor();


s/foor/foo/


+
+2. You need to feed this declaration to block-coroutine-wrapper script.


to the block-


+   For this, add .h (or .c) file with the declaration to
+   ``input: files(...)`` list of ``block_gen_c`` target declaration in
+   ``block/meson.build``
+
+You are done. On build, coroutine wrappers will be generated in


s/On/During the/


+``/block/block-gen.c``.


...but 2 in the .rst.  Presumably, the .rst steps belong in the commit 
message as well.



+++ b/block/block-gen.h



+++ b/include/block/block.h
@@ -10,6 +10,16 @@
 #include "block/blockjob.h"
 #include "qemu/hbitmap.h"
 
+/*

+ * generated_co_wrapper
+ *
+ * Function specifier, which does nothing but marking functions to be


s/marking/mark/


+ * generated by scripts/block-coroutine-wrapper.py
+ *
+ * Read more in docs/devel/block-coroutine-wrapper.rst
+ */
+#define generated_co_wrapper
+
 /* block.c */
 typedef struct BlockDriver BlockDriver;
 typedef struct BdrvChild BdrvChild;
diff --git a/block/meson.build b/block/meson.build
index a3e56b7cd1..88ad73583a 100644
--- a/block/meson.build
+++ b/block/meson.build
@@ -107,6 +107,14 @@ module_block_h = custom_target('module_block.h',
command: [module_block_py, '@OUTPUT0@', modsrc])
 block_ss.add(module_block_h)
 
+wrapper_py = find_program('../scripts/block-coroutine-wrapper.py')

+block_gen_c = custom_target('block-gen.c',
+output: 'block-gen.c',
+input: 

Re: [PATCH v2 27/38] qapi/gen.py: Remove unused parameter

2020-09-23 Thread Cleber Rosa
On Tue, Sep 22, 2020 at 05:00:50PM -0400, John Snow wrote:
> module_basename doesn't use the 'what' argument, so remove it.
> 
> Signed-off-by: John Snow 

Reviewed-by: Cleber Rosa 


signature.asc
Description: PGP signature


Re: [PATCH v2 26/38] qapi/gen.py: Enable checking with mypy

2020-09-23 Thread Cleber Rosa
On Tue, Sep 22, 2020 at 05:00:49PM -0400, John Snow wrote:
> Signed-off-by: John Snow 
> ---
>  scripts/qapi/mypy.ini | 5 -
>  1 file changed, 5 deletions(-)
> 
> diff --git a/scripts/qapi/mypy.ini b/scripts/qapi/mypy.ini
> index 43c8bd1973..dbfeda748c 100644
> --- a/scripts/qapi/mypy.ini
> +++ b/scripts/qapi/mypy.ini
> @@ -19,11 +19,6 @@ disallow_untyped_defs = False
>  disallow_incomplete_defs = False
>  check_untyped_defs = False
>  
> -[mypy-qapi.gen]
> -disallow_untyped_defs = False
> -disallow_incomplete_defs = False
> -check_untyped_defs = False
> -
>  [mypy-qapi.introspect]
>  disallow_untyped_defs = False
>  disallow_incomplete_defs = False
> -- 
> 2.26.2
> 

Like I mentioned before, I'd squash this together with the actual
changes that enable this increased coverage.

Anyway,

Reviewed-by: Cleber Rosa 
Tested-by: Cleber Rosa 


signature.asc
Description: PGP signature


Re: [PATCH v2 24/38] qapi/gen.py: Fix edge-case of _is_user_module

2020-09-23 Thread John Snow

On 9/23/20 7:08 PM, Cleber Rosa wrote:

On Tue, Sep 22, 2020 at 05:00:47PM -0400, John Snow wrote:

The edge case is that if the name is '', this expression returns a
string instead of a bool, which violates our declared type.

Signed-off-by: John Snow 
---
  scripts/qapi/gen.py | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
index 9898d513ae..cb2b2655c3 100644
--- a/scripts/qapi/gen.py
+++ b/scripts/qapi/gen.py
@@ -251,7 +251,7 @@ def __init__(self, prefix, what, user_blurb, builtin_blurb, 
pydoc):
  
  @staticmethod

  def _is_user_module(name):
-return name and not name.startswith('./')
+return name is not None and not name.startswith('./')


Another possibility here that handles the empty string situation and
will never return anything but a bool:

   return all([name, not name.startswith('./')])

Either way,

Reviewed-by: Cleber Rosa 



I wound up changing this per ehabkost's review.

--js




Re: [PATCH v2 22/38] qapi/source.py: add type hint annotations

2020-09-23 Thread John Snow

On 9/23/20 6:36 PM, Cleber Rosa wrote:

On Tue, Sep 22, 2020 at 05:00:45PM -0400, John Snow wrote:

Annotations do not change runtime behavior.
This commit *only* adds annotations.

Signed-off-by: John Snow 
---
  scripts/qapi/mypy.ini  |  5 -
  scripts/qapi/source.py | 31 ++-
  2 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/scripts/qapi/mypy.ini b/scripts/qapi/mypy.ini
index 9da1dccef4..43c8bd1973 100644
--- a/scripts/qapi/mypy.ini
+++ b/scripts/qapi/mypy.ini
@@ -39,11 +39,6 @@ disallow_untyped_defs = False
  disallow_incomplete_defs = False
  check_untyped_defs = False
  
-[mypy-qapi.source]

-disallow_untyped_defs = False
-disallow_incomplete_defs = False
-check_untyped_defs = False
-


This is what I meant in my comment in the previous patch.  It looks
like a mix of commit grannurality styles.  Not a blocker though.



Yep. Just how the chips fell. Some files were just very quick to cleanup 
and I didn't have to refactor them much when I split things out, so the 
enablements got rolled in.


I will, once reviews are in (and there is a commitment to merge), try to 
squash things where it seems appropriate.



  [mypy-qapi.types]
  disallow_untyped_defs = False
  disallow_incomplete_defs = False
diff --git a/scripts/qapi/source.py b/scripts/qapi/source.py
index e97b9a8e15..1cc6a5b82d 100644
--- a/scripts/qapi/source.py
+++ b/scripts/qapi/source.py
@@ -11,37 +11,42 @@
  
  import copy

  import sys
+from typing import List, Optional, TypeVar
  
  
  class QAPISchemaPragma:

-def __init__(self):
+def __init__(self) -> None:


I don't follow the reason for typing this...


  # Are documentation comments required?
  self.doc_required = False
  # Whitelist of commands allowed to return a non-dictionary
-self.returns_whitelist = []
+self.returns_whitelist: List[str] = []
  # Whitelist of entities allowed to violate case conventions
-self.name_case_whitelist = []
+self.name_case_whitelist: List[str] = []
  
  
  class QAPISourceInfo:

-def __init__(self, fname, line, parent):
+T = TypeVar('T', bound='QAPISourceInfo')
+
+def __init__(self: T, fname: str, line: int, parent: Optional[T]):


And not this... to tune my review approach, should I assume that this
series intends to add complete type hints or not?



This is a mypy quirk you've discovered that I've simply forgotten about.

When __init__ has *no* arguments, you need to annotate its return to 
explain to mypy that you have fully typed that method. It's a sentinel 
that says "Please type check this class!"


When __init__ has some arguments, you only need to type those arguments 
and not the return type. The sentinel is not needed.


__init__ *never* returns anything, so I opted to omit this useless 
annotation whenever it was possible to do so.



- Cleber.






Re: [PATCH v2 25/38] qapi/gen.py: add type hint annotations

2020-09-23 Thread Cleber Rosa
On Tue, Sep 22, 2020 at 05:00:48PM -0400, John Snow wrote:
> Annotations do not change runtime behavior.
> This commit *only* adds annotations.
> 
> Signed-off-by: John Snow 
> ---
>  scripts/qapi/gen.py | 102 +++-
>  1 file changed, 53 insertions(+), 49 deletions(-)
> 
> diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
> index cb2b2655c3..df8cf8271c 100644
> --- a/scripts/qapi/gen.py
> +++ b/scripts/qapi/gen.py
> @@ -17,7 +17,7 @@
>  import errno
>  import os
>  import re
> -from typing import Optional
> +from typing import Dict, Generator, List, Optional, Tuple
>  
>  from .common import (
>  c_fname,
> @@ -32,31 +32,31 @@
>  QAPISchemaObjectType,
>  QAPISchemaVisitor,
>  )
> +from .source import QAPISourceInfo
>  
>  
>  class QAPIGen:
> -
> -def __init__(self, fname):
> +def __init__(self, fname: Optional[str]):
>  self.fname = fname
>  self._preamble = ''
>  self._body = ''
>  
> -def preamble_add(self, text):
> +def preamble_add(self, text: str) -> None:
>  self._preamble += text
>  
> -def add(self, text):
> +def add(self, text: str) -> None:
>  self._body += text
>  
> -def get_content(self):
> +def get_content(self) -> str:
>  return self._top() + self._preamble + self._body + self._bottom()
>  
> -def _top(self):
> +def _top(self) -> str:
>  return ''
>  
> -def _bottom(self):
> +def _bottom(self) -> str:
>  return ''
>  
> -def write(self, output_dir):
> +def write(self, output_dir: str) -> None:
>  # Include paths starting with ../ are used to reuse modules of the 
> main
>  # schema in specialised schemas. Don't overwrite the files that are
>  # already generated for the main schema.
> @@ -81,7 +81,7 @@ def write(self, output_dir):
>  f.close()
>  
>  
> -def _wrap_ifcond(ifcond, before, after):
> +def _wrap_ifcond(ifcond: List[str], before: str, after: str) -> str:
>  if before == after:
>  return after   # suppress empty #if ... #endif
>  
> @@ -121,40 +121,38 @@ def build_params(arg_type: 
> Optional[QAPISchemaObjectType],
>  
>  
>  class QAPIGenCCode(QAPIGen):
> -
> -def __init__(self, fname):
> +def __init__(self, fname: Optional[str]):
>  super().__init__(fname)
> -self._start_if = None
> +self._start_if: Optional[Tuple[List[str], str, str]] = None
>  
> -def start_if(self, ifcond):
> +def start_if(self, ifcond: List[str]) -> None:
>  assert self._start_if is None
>  self._start_if = (ifcond, self._body, self._preamble)
>  
> -def end_if(self):
> +def end_if(self) -> None:
>  assert self._start_if
>  self._wrap_ifcond()
>  self._start_if = None
>  
> -def _wrap_ifcond(self):
> +def _wrap_ifcond(self) -> None:
>  self._body = _wrap_ifcond(self._start_if[0],
>self._start_if[1], self._body)
>  self._preamble = _wrap_ifcond(self._start_if[0],
>self._start_if[2], self._preamble)
>  
> -def get_content(self):
> +def get_content(self) -> str:
>  assert self._start_if is None
>  return super().get_content()
>  
>  
>  class QAPIGenC(QAPIGenCCode):
> -
> -def __init__(self, fname, blurb, pydoc):
> +def __init__(self, fname: str, blurb: str, pydoc: str):
>  super().__init__(fname)
>  self._blurb = blurb
>  self._copyright = '\n * '.join(re.findall(r'^Copyright .*', pydoc,
>re.MULTILINE))
>  
> -def _top(self):
> +def _top(self) -> str:
>  return mcgen('''
>  /* AUTOMATICALLY GENERATED, DO NOT MODIFY */
>  
> @@ -170,7 +168,7 @@ def _top(self):
>  ''',
>   blurb=self._blurb, copyright=self._copyright)
>  
> -def _bottom(self):
> +def _bottom(self) -> str:
>  return mcgen('''
>  
>  /* Dummy declaration to prevent empty .o file */
> @@ -180,16 +178,16 @@ def _bottom(self):
>  
>  
>  class QAPIGenH(QAPIGenC):
> -
> -def _top(self):
> +def _top(self) -> str:
>  return super()._top() + guardstart(self.fname)
>  
> -def _bottom(self):
> +def _bottom(self) -> str:
>  return guardend(self.fname)
>  
>  
>  @contextmanager
> -def ifcontext(ifcond, *args):
> +def ifcontext(ifcond: List[str],
> +  *args: QAPIGenCCode) -> Generator[None, None, None]:

IIUC, this could simply be "Iterator[None]" instead of
"Generator[None, None, None]".

Anyway,

Reviewed-by: Cleber Rosa 


signature.asc
Description: PGP signature


Re: [PATCH v2 21/38] qapi/commands.py: enable checking with mypy

2020-09-23 Thread John Snow

On 9/23/20 6:21 PM, Cleber Rosa wrote:

On Tue, Sep 22, 2020 at 05:00:44PM -0400, John Snow wrote:

Signed-off-by: John Snow 
---
  scripts/qapi/mypy.ini | 5 -
  1 file changed, 5 deletions(-)

diff --git a/scripts/qapi/mypy.ini b/scripts/qapi/mypy.ini
index b668776d94..9da1dccef4 100644
--- a/scripts/qapi/mypy.ini
+++ b/scripts/qapi/mypy.ini
@@ -4,11 +4,6 @@ strict_optional = False
  disallow_untyped_calls = False
  python_version = 3.6
  
-[mypy-qapi.commands]

-disallow_untyped_defs = False
-disallow_incomplete_defs = False
-check_untyped_defs = False
-
  [mypy-qapi.doc]
  disallow_subclassing_any = False
  disallow_untyped_defs = False
--
2.26.2



IMO, this increase of strictness for "commands" would make more sense
to be squashed together with the previous changes on "commands.py".
Not only here, but for the other patches for the other modules too.

Anyway,

Reviewed-by: Cleber Rosa 



Admittedly, the only reason I *didn't* is because these patches have 
been reordered a *lot* and in some cases, it helped me to have distinct 
"This patch is last and enables the checks!" commits.


(I am hedging my bets that more re-ordering is in my future.)

I will squash the "Enable such-and-such" commits with whatever fixed the 
last error for final inclusion, but I might keep them separate for now 
just for my own convenience.


Sorry for the volume.

--js




Re: [PATCH v2 24/38] qapi/gen.py: Fix edge-case of _is_user_module

2020-09-23 Thread Cleber Rosa
On Wed, Sep 23, 2020 at 07:10:35PM -0400, Cleber Rosa wrote:
> On Wed, Sep 23, 2020 at 02:33:35PM -0400, Eduardo Habkost wrote:
> > On Wed, Sep 23, 2020 at 02:29:28PM -0400, John Snow wrote:
> > > On 9/23/20 11:17 AM, Eduardo Habkost wrote:
> > > > This changes behavior if name=='', and I guess this is OK, but
> > > > I'm not sure.  I miss documentation on `visit_module()`,
> > > > `visit_include()`, and `_is_user_module()`.  I don't know what
> > > > `name` means here, and what is a "user module".
> > > > 
> > > 
> > > Good spot, I missed that.
> > >
> 
> Nice catch indeed.
> 
> > > I can probably do: bool(name and not name.startswith('./'))
> > >
> 
> In this case I like my previous suggestion even better. :)
> 
> - Cleber.

Never mind me... I noticed that this actually gets called with None.

- Cleber.


signature.asc
Description: PGP signature


Re: [PATCH v2 24/38] qapi/gen.py: Fix edge-case of _is_user_module

2020-09-23 Thread Cleber Rosa
On Wed, Sep 23, 2020 at 07:08:50PM -0400, Cleber Rosa wrote:
> On Tue, Sep 22, 2020 at 05:00:47PM -0400, John Snow wrote:
> > The edge case is that if the name is '', this expression returns a
> > string instead of a bool, which violates our declared type.
> > 
> > Signed-off-by: John Snow 
> > ---
> >  scripts/qapi/gen.py | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
> > index 9898d513ae..cb2b2655c3 100644
> > --- a/scripts/qapi/gen.py
> > +++ b/scripts/qapi/gen.py
> > @@ -251,7 +251,7 @@ def __init__(self, prefix, what, user_blurb, 
> > builtin_blurb, pydoc):
> >  
> >  @staticmethod
> >  def _is_user_module(name):
> > -return name and not name.startswith('./')
> > +return name is not None and not name.startswith('./')
> 
> Another possibility here that handles the empty string situation and
> will never return anything but a bool:
> 
>   return all([name, not name.startswith('./')])
>

Never mind me... I noticed that this actually gets called with None.

- Cleber.


signature.asc
Description: PGP signature


Re: [PATCH v2 24/38] qapi/gen.py: Fix edge-case of _is_user_module

2020-09-23 Thread Cleber Rosa
On Wed, Sep 23, 2020 at 02:33:35PM -0400, Eduardo Habkost wrote:
> On Wed, Sep 23, 2020 at 02:29:28PM -0400, John Snow wrote:
> > On 9/23/20 11:17 AM, Eduardo Habkost wrote:
> > > This changes behavior if name=='', and I guess this is OK, but
> > > I'm not sure.  I miss documentation on `visit_module()`,
> > > `visit_include()`, and `_is_user_module()`.  I don't know what
> > > `name` means here, and what is a "user module".
> > > 
> > 
> > Good spot, I missed that.
> >

Nice catch indeed.

> > I can probably do: bool(name and not name.startswith('./'))
> >

In this case I like my previous suggestion even better. :)

- Cleber.


signature.asc
Description: PGP signature


Re: [PATCH v2 24/38] qapi/gen.py: Fix edge-case of _is_user_module

2020-09-23 Thread Cleber Rosa
On Tue, Sep 22, 2020 at 05:00:47PM -0400, John Snow wrote:
> The edge case is that if the name is '', this expression returns a
> string instead of a bool, which violates our declared type.
> 
> Signed-off-by: John Snow 
> ---
>  scripts/qapi/gen.py | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
> index 9898d513ae..cb2b2655c3 100644
> --- a/scripts/qapi/gen.py
> +++ b/scripts/qapi/gen.py
> @@ -251,7 +251,7 @@ def __init__(self, prefix, what, user_blurb, 
> builtin_blurb, pydoc):
>  
>  @staticmethod
>  def _is_user_module(name):
> -return name and not name.startswith('./')
> +return name is not None and not name.startswith('./')

Another possibility here that handles the empty string situation and
will never return anything but a bool:

  return all([name, not name.startswith('./')])

Either way,

Reviewed-by: Cleber Rosa 


signature.asc
Description: PGP signature


Re: [PATCH v2 32/38] qapi/introspect.py: create a typed 'Node' data structure

2020-09-23 Thread John Snow

On 9/23/20 2:41 PM, Eduardo Habkost wrote:

On Tue, Sep 22, 2020 at 05:00:55PM -0400, John Snow wrote:

Replacing the un-typed tuple, add a typed Node that we can add typed
metadata to.

Signed-off-by: John Snow 


This is the most complex patch so far, and it's very hard to
understand what it does without type annotations.

Have you consider adding type annotations to the code before
patch 30/38 (even if using `object` in some parts), so we can
make this easier to review?

In case it's useful, below is an attempt to add type annotations
to the old code.  It can be applied after patch 29/38.  It reuses
portions of patch 33/38.

Signed-off-by: John Snow 
Signed-off-by: Eduardo Habkost 
---
  scripts/qapi/introspect.py | 138 ++---
  scripts/qapi/mypy.ini  |   5 --
  scripts/qapi/schema.py |   2 +-
  3 files changed, 100 insertions(+), 45 deletions(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index b036fcf9ce7..4eaebdef58b 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -10,6 +10,17 @@ This work is licensed under the terms of the GNU GPL, 
version 2.
  See the COPYING file in the top-level directory.
  """
  
+from typing import (

+Dict,
+Generic,
+List,
+NamedTuple,
+Optional,
+Sequence,
+TypeVar,
+Tuple
+)
+
  from .common import (
  c_name,
  gen_endif,
@@ -17,25 +28,48 @@ from .common import (
  mcgen,
  )
  from .gen import QAPISchemaMonolithicCVisitor
-from .schema import (QAPISchemaArrayType, QAPISchemaBuiltinType,
- QAPISchemaType)
-
-
-def _make_tree(obj, ifcond, features, extra=None):
+from .schema import (
+QAPISchema,
+QAPISchemaArrayType,
+QAPISchemaBuiltinType,
+QAPISchemaEntity,
+QAPISchemaEnumMember,
+QAPISchemaFeature,
+QAPISchemaObjectType,
+QAPISchemaObjectTypeMember,
+QAPISchemaType,
+QAPISchemaVariant,
+QAPISchemaVariants,
+)
+from .source import QAPISourceInfo
+
+T = TypeVar('T')
+# this should actually be: Union[str, list, dict, bool, 'AnnotatedNode']
+# but mypy doesn't support recursive types
+TreeNode = object
+TreeDict = Dict[str, TreeNode]
+Extra = Dict[str, object]
+AnnotatedNode = Tuple[T, Extra]
+
+def _make_tree(obj: TreeDict, ifcond: List[str],

   

Technically untrue! obj may be a SchemaInfo-like dict, or a string.
(And I will tell you why mypy didn't catch this!)


+   features: List[QAPISchemaFeature],
+   extra: Optional[Extra] = None) -> TreeNode:
  if extra is None:
  extra = {}
  if ifcond:
  extra['if'] = ifcond
  if features:
-obj['features'] = [(f.name, {'if': f.ifcond}) for f in features]
+obj['features'] = ([(f.name, {'if': f.ifcond}) for f in features])
  if extra:
  return (obj, extra)
  return obj
  
  
-def _tree_to_qlit(obj, level=0, suppress_first_indent=False):

+def _tree_to_qlit(obj: TreeNode,
+  level: int = 0,
+  suppress_first_indent : bool = False) -> str:
  
-def indent(level):

+def indent(level: int) -> str:
  return level * 4 * ' '
  
  if isinstance(obj, tuple):

@@ -85,21 +119,20 @@ def _tree_to_qlit(obj, level=0, 
suppress_first_indent=False):
  return ret
  
  
-def to_c_string(string):

+def to_c_string(string: str) -> str:
  return '"' + string.replace('\\', r'\\').replace('"', r'\"') + '"'
  
  
  class QAPISchemaGenIntrospectVisitor(QAPISchemaMonolithicCVisitor):

-
-def __init__(self, prefix, unmask):
+def __init__(self, prefix: str, unmask: bool):
  super().__init__(
  prefix, 'qapi-introspect',
  ' * QAPI/QMP schema introspection', __doc__)
  self._unmask = unmask
-self._schema = None
-self._trees = []
-self._used_types = []
-self._name_map = {}
+self._schema: Optional[QAPISchema] = None
+self._trees: List[TreeNode] = []
+self._used_types: List[QAPISchemaType] = []
+self._name_map: Dict[str, str] = {}
  self._genc.add(mcgen('''
  #include "qemu/osdep.h"
  #include "%(prefix)sqapi-introspect.h"
@@ -107,10 +140,10 @@ class 
QAPISchemaGenIntrospectVisitor(QAPISchemaMonolithicCVisitor):
  ''',
   prefix=prefix))
  
-def visit_begin(self, schema):

+def visit_begin(self, schema: QAPISchema) -> None:
  self._schema = schema
  
-def visit_end(self):

+def visit_end(self) -> None:
  # visit the types that are actually used
  for typ in self._used_types:
  typ.visit(self)
@@ -132,18 +165,18 @@ const QLitObject %(c_name)s = %(c_string)s;
  self._used_types = []
  self._name_map = {}
  
-def visit_needed(self, entity):

+def visit_needed(self, entity: QAPISchemaEntity) -> bool:
  # Ignore types on first pass; visit_end() will pick up used types

Re: [PATCH v2 23/38] qapi/source.py: delint with pylint

2020-09-23 Thread Cleber Rosa
On Tue, Sep 22, 2020 at 05:00:46PM -0400, John Snow wrote:
> Shush an error and leave a hint for future cleanups when we're allowed
> to use Python 3.7+.
> 
> Signed-off-by: John Snow 

Reviewed-by: Cleber Rosa 
Tested-by: Cleber Rosa 


signature.asc
Description: PGP signature


Re: [PATCH v2 22/38] qapi/source.py: add type hint annotations

2020-09-23 Thread Cleber Rosa
On Tue, Sep 22, 2020 at 05:00:45PM -0400, John Snow wrote:
> Annotations do not change runtime behavior.
> This commit *only* adds annotations.
> 
> Signed-off-by: John Snow 
> ---
>  scripts/qapi/mypy.ini  |  5 -
>  scripts/qapi/source.py | 31 ++-
>  2 files changed, 18 insertions(+), 18 deletions(-)
> 
> diff --git a/scripts/qapi/mypy.ini b/scripts/qapi/mypy.ini
> index 9da1dccef4..43c8bd1973 100644
> --- a/scripts/qapi/mypy.ini
> +++ b/scripts/qapi/mypy.ini
> @@ -39,11 +39,6 @@ disallow_untyped_defs = False
>  disallow_incomplete_defs = False
>  check_untyped_defs = False
>  
> -[mypy-qapi.source]
> -disallow_untyped_defs = False
> -disallow_incomplete_defs = False
> -check_untyped_defs = False
> -

This is what I meant in my comment in the previous patch.  It looks
like a mix of commit grannurality styles.  Not a blocker though.

>  [mypy-qapi.types]
>  disallow_untyped_defs = False
>  disallow_incomplete_defs = False
> diff --git a/scripts/qapi/source.py b/scripts/qapi/source.py
> index e97b9a8e15..1cc6a5b82d 100644
> --- a/scripts/qapi/source.py
> +++ b/scripts/qapi/source.py
> @@ -11,37 +11,42 @@
>  
>  import copy
>  import sys
> +from typing import List, Optional, TypeVar
>  
>  
>  class QAPISchemaPragma:
> -def __init__(self):
> +def __init__(self) -> None:

I don't follow the reason for typing this...

>  # Are documentation comments required?
>  self.doc_required = False
>  # Whitelist of commands allowed to return a non-dictionary
> -self.returns_whitelist = []
> +self.returns_whitelist: List[str] = []
>  # Whitelist of entities allowed to violate case conventions
> -self.name_case_whitelist = []
> +self.name_case_whitelist: List[str] = []
>  
>  
>  class QAPISourceInfo:
> -def __init__(self, fname, line, parent):
> +T = TypeVar('T', bound='QAPISourceInfo')
> +
> +def __init__(self: T, fname: str, line: int, parent: Optional[T]):

And not this... to tune my review approach, should I assume that this
series intends to add complete type hints or not?

- Cleber.


signature.asc
Description: PGP signature


Re: [PATCH v4 0/2] qemu/atomic.h: rename atomic_ to qatomic_

2020-09-23 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20200923151901.745277-1-phi...@redhat.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20200923151901.745277-1-phi...@redhat.com
Subject: [PATCH v4 0/2] qemu/atomic.h: rename atomic_ to qatomic_

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

From https://github.com/patchew-project/qemu
 - [tag update]  patchew/20200923151901.745277-1-phi...@redhat.com -> 
patchew/20200923151901.745277-1-phi...@redhat.com
Switched to a new branch 'test'
424f21a qemu/atomic.h: rename atomic_ to qatomic_
90bd4fa qemu/atomic: Update coding style to make checkpatch.pl happier

=== OUTPUT BEGIN ===
1/2 Checking commit 90bd4facd2bb (qemu/atomic: Update coding style to make 
checkpatch.pl happier)
ERROR: Use of volatile is usually wrong, please add a comment
#23: FILE: include/qemu/atomic.h:328:
+#define atomic_read__nocheck(p)   (*(__typeof__(*(p)) volatile *) (p))

ERROR: Use of volatile is usually wrong, please add a comment
#24: FILE: include/qemu/atomic.h:329:
+#define atomic_set__nocheck(p, i) ((*(__typeof__(*(p)) volatile *) (p)) = (i))

total: 2 errors, 0 warnings, 50 lines checked

Patch 1/2 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

2/2 Checking commit 424f21a3295e (qemu/atomic.h: rename atomic_ to qatomic_)
ERROR: Macros with multiple statements should be enclosed in a do - while loop
#2801: FILE: include/qemu/atomic.h:152:
+#define qatomic_rcu_read__nocheck(ptr, valptr)   \
+__atomic_load(ptr, valptr, __ATOMIC_RELAXED);\
 smp_read_barrier_depends();

ERROR: Use of volatile is usually wrong, please add a comment
#2946: FILE: include/qemu/atomic.h:333:
+#define qatomic_read__nocheck(p)   (*(__typeof__(*(p)) volatile *) (p))

ERROR: Use of volatile is usually wrong, please add a comment
#2947: FILE: include/qemu/atomic.h:334:
+#define qatomic_set__nocheck(p, i) ((*(__typeof__(*(p)) volatile *) (p)) = (i))

ERROR: memory barrier without comment
#3024: FILE: include/qemu/atomic.h:395:
+#define qatomic_xchg(ptr, i)(smp_mb(), __sync_lock_test_and_set(ptr, i))

total: 4 errors, 0 warnings, 6269 lines checked

Patch 2/2 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20200923151901.745277-1-phi...@redhat.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [PATCH v2 21/38] qapi/commands.py: enable checking with mypy

2020-09-23 Thread Cleber Rosa
On Tue, Sep 22, 2020 at 05:00:44PM -0400, John Snow wrote:
> Signed-off-by: John Snow 
> ---
>  scripts/qapi/mypy.ini | 5 -
>  1 file changed, 5 deletions(-)
> 
> diff --git a/scripts/qapi/mypy.ini b/scripts/qapi/mypy.ini
> index b668776d94..9da1dccef4 100644
> --- a/scripts/qapi/mypy.ini
> +++ b/scripts/qapi/mypy.ini
> @@ -4,11 +4,6 @@ strict_optional = False
>  disallow_untyped_calls = False
>  python_version = 3.6
>  
> -[mypy-qapi.commands]
> -disallow_untyped_defs = False
> -disallow_incomplete_defs = False
> -check_untyped_defs = False
> -
>  [mypy-qapi.doc]
>  disallow_subclassing_any = False
>  disallow_untyped_defs = False
> -- 
> 2.26.2
> 

IMO, this increase of strictness for "commands" would make more sense
to be squashed together with the previous changes on "commands.py".
Not only here, but for the other patches for the other modules too.

Anyway,

Reviewed-by: Cleber Rosa 


signature.asc
Description: PGP signature


Re: [PATCH v2 20/38] qapi/commands.py: add notational type hints

2020-09-23 Thread Cleber Rosa
On Tue, Sep 22, 2020 at 05:00:43PM -0400, John Snow wrote:
> Signed-off-by: John Snow 

Reviewed-by: Cleber Rosa 


signature.asc
Description: PGP signature


Re: [PATCH v2 36/38] qapi/visit.py: assert tag_member contains a QAPISchemaEnumType

2020-09-23 Thread John Snow

On 9/23/20 3:15 PM, Eduardo Habkost wrote:

On Tue, Sep 22, 2020 at 05:00:59PM -0400, John Snow wrote:

Signed-off-by: John Snow 


This for making mypy happy, correct?  An explanation in the commit
message would be nice.

Reviewed-by: Eduardo Habkost 



Yes, it's for mypy -- but it's a runtime visible change. Technically our 
type system isn't mature enough to express this constraint natively, so 
it's being carried around as developer knowledge.


This formalizes that knowledge, albeit in a very crude way.

I've amended the commit msg.




Re: [PATCH v2 35/38] qapi/types.py: remove one-letter variables

2020-09-23 Thread John Snow

On 9/23/20 3:14 PM, Eduardo Habkost wrote:

I'm not sure I like this weird expression, but I believe asking
for a 120-patch cleanup series to be respun because of a tiny
style issue would be counterproductive, so:

Reviewed-by: Eduardo Habkost


I was trying to reduce the indent level to accommodate the longer names, 
but python ternaries *are* pretty weird.


It'd be nice to enforce always having a variants object instead (even if 
it's empty!) and then add __bool__ and __iter__ methods to 
QAPISchemaVariants such that you could always do:


"if variants"

or

"for variant in variants"

but we're not there just yet... should I just put it back the way it 
was, with the deep nesting?


--js




Re: [PATCH] docs: Better mention of qemu-img amend limitations

2020-09-23 Thread Nir Soffer
On Wed, Sep 23, 2020 at 11:38 PM Eric Blake  wrote:
>
> Missed during merge resolution of commit bc5ee6da71.
>
> Signed-off-by: Eric Blake 
> ---
>  docs/tools/qemu-img.rst | 4 
>  1 file changed, 4 insertions(+)
>
> diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
> index c35bd6482203..2b5891b54db7 100644
> --- a/docs/tools/qemu-img.rst
> +++ b/docs/tools/qemu-img.rst
> @@ -265,6 +265,10 @@ Command description:
>--force allows some unsafe operations. Currently for -f luks, it allows to
>erase the last encryption key, and to overwrite an active encryption key.
>
> +  The set of options that can be amended are dependent on the image
> +  format, but note that amending the backing chain relationship should
> +  instead be performed with ``qemu-img rebase``.

Because of the backing format?

> +
>  .. option:: bench [-c COUNT] [-d DEPTH] [-f FMT] 
> [--flush-interval=FLUSH_INTERVAL] [-i AIO] [-n] [--no-drain] [-o OFFSET] 
> [--pattern=PATTERN] [-q] [-s BUFFER_SIZE] [-S STEP_SIZE] [-t CACHE] [-w] [-U] 
> FILENAME
>
>Run a simple sequential I/O benchmark on the specified image. If ``-w`` is
> --
> 2.28.0
>
>




[Bug 1896096] Re: Git version: Build process is broken in block_curl.c.o

2020-09-23 Thread Toolybird
v2 patches appear to work fine in both test scenarios. Thanks again.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1896096

Title:
  Git version: Build process is broken in block_curl.c.o

Status in QEMU:
  Invalid

Bug description:
  Gcc version: 10.2.0
  Glusterfs: 8.1
  Libguestfs: 1.42

  Configure options used:

  configure \
  --prefix=/usr \
  --sysconfdir=/etc \
  --localstatedir=/var \
  --libexecdir=/usr/lib/qemu \
  --extra-ldflags="$LDFLAGS" \
  --smbd=/usr/bin/smbd \
  --enable-modules \
  --enable-sdl \
  --disable-werror \
  --enable-slirp=system \
  --enable-xfsctl \
  --audio-drv-list="pa alsa sdl"
  
  Error log attached. Here is the beginning:

  /usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../lib/Scrt1.o: 
in function `_start':
  (.text+0x24): undefined reference to `main'
  /usr/bin/ld: libblock-curl.a(block_curl.c.o): in function `curl_block_init':

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1896096/+subscriptions



Re: [PATCH v2 31/38] qapi/introspect.py: add _gen_features helper

2020-09-23 Thread Eduardo Habkost
On Wed, Sep 23, 2020 at 05:43:45PM -0400, John Snow wrote:
> On 9/23/20 12:35 PM, Eduardo Habkost wrote:
> > I believe these two lines above should be removed, as suggested
> > in patch 30, but let's ignore that for now.
> > 
> 
> Yup, headed there.
> 
> > > -if features:
> > > -obj['features'] = [(f.name, Extra(None, f.ifcond)) for f in 
> > > features]
> > I can't say I understand completely why moving these two lines
> > outside _make_tree() is useful, but if it makes the cleanup work
> > you did easier, I trust this is the right thing to do.  The
> > changes look correct.
> 
> The basic premise is:
> 
> Why pass information you want to add to obj['features'] to a function to
> make that assignment, when you could just perform that assignment yourself?
> 
> Otherwise, _make_tree, which accepts any arbitrary object (not just dicts!)
> has to interrogate its arguments to make sure you gave it a dict when you
> give it a features argument.

Oh, I was not aware that obj could be not a dictionary.  In this
case, it makes lots of sense to move the magic outside the
function.

> 
> Type-wise, it's cleaner to perform this transformation when we KNOW we have
> an object than it is to defer to a more abstracted function and
> assert/downcast back to more specific types.

-- 
Eduardo




Re: [PATCH v2 32/38] qapi/introspect.py: create a typed 'Node' data structure

2020-09-23 Thread John Snow

On 9/23/20 2:41 PM, Eduardo Habkost wrote:

On Tue, Sep 22, 2020 at 05:00:55PM -0400, John Snow wrote:

Replacing the un-typed tuple, add a typed Node that we can add typed
metadata to.

Signed-off-by: John Snow 


This is the most complex patch so far, and it's very hard to
understand what it does without type annotations.



Mmm, sorry about that.


Have you consider adding type annotations to the code before
patch 30/38 (even if using `object` in some parts), so we can
make this easier to review?



If you feel like it isn't just noise to learn types we're about to 
destroy with something else, I'll try.



In case it's useful, below is an attempt to add type annotations
to the old code.  It can be applied after patch 29/38.  It reuses
portions of patch 33/38.



OK. End result is I will squash the Extra and Node types together, but I 
need to figure out how to make it look nice for the review history.


Gimmie a few to make a mess and I'll try to put it back together afterward.


Signed-off-by: John Snow 
Signed-off-by: Eduardo Habkost 
---
  scripts/qapi/introspect.py | 138 ++---
  scripts/qapi/mypy.ini  |   5 --
  scripts/qapi/schema.py |   2 +-
  3 files changed, 100 insertions(+), 45 deletions(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index b036fcf9ce7..4eaebdef58b 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -10,6 +10,17 @@ This work is licensed under the terms of the GNU GPL, 
version 2.
  See the COPYING file in the top-level directory.
  """
  
+from typing import (

+Dict,
+Generic,
+List,
+NamedTuple,
+Optional,
+Sequence,
+TypeVar,
+Tuple
+)
+
  from .common import (
  c_name,
  gen_endif,
@@ -17,25 +28,48 @@ from .common import (
  mcgen,
  )
  from .gen import QAPISchemaMonolithicCVisitor
-from .schema import (QAPISchemaArrayType, QAPISchemaBuiltinType,
- QAPISchemaType)
-
-
-def _make_tree(obj, ifcond, features, extra=None):
+from .schema import (
+QAPISchema,
+QAPISchemaArrayType,
+QAPISchemaBuiltinType,
+QAPISchemaEntity,
+QAPISchemaEnumMember,
+QAPISchemaFeature,
+QAPISchemaObjectType,
+QAPISchemaObjectTypeMember,
+QAPISchemaType,
+QAPISchemaVariant,
+QAPISchemaVariants,
+)
+from .source import QAPISourceInfo
+
+T = TypeVar('T')
+# this should actually be: Union[str, list, dict, bool, 'AnnotatedNode']
+# but mypy doesn't support recursive types
+TreeNode = object
+TreeDict = Dict[str, TreeNode]
+Extra = Dict[str, object]
+AnnotatedNode = Tuple[T, Extra]
+
+def _make_tree(obj: TreeDict, ifcond: List[str],
+   features: List[QAPISchemaFeature],
+   extra: Optional[Extra] = None) -> TreeNode:
  if extra is None:
  extra = {}
  if ifcond:
  extra['if'] = ifcond
  if features:
-obj['features'] = [(f.name, {'if': f.ifcond}) for f in features]
+obj['features'] = ([(f.name, {'if': f.ifcond}) for f in features])
  if extra:
  return (obj, extra)
  return obj
  
  
-def _tree_to_qlit(obj, level=0, suppress_first_indent=False):

+def _tree_to_qlit(obj: TreeNode,
+  level: int = 0,
+  suppress_first_indent : bool = False) -> str:
  
-def indent(level):

+def indent(level: int) -> str:
  return level * 4 * ' '
  
  if isinstance(obj, tuple):

@@ -85,21 +119,20 @@ def _tree_to_qlit(obj, level=0, 
suppress_first_indent=False):
  return ret
  
  
-def to_c_string(string):

+def to_c_string(string: str) -> str:
  return '"' + string.replace('\\', r'\\').replace('"', r'\"') + '"'
  
  
  class QAPISchemaGenIntrospectVisitor(QAPISchemaMonolithicCVisitor):

-
-def __init__(self, prefix, unmask):
+def __init__(self, prefix: str, unmask: bool):
  super().__init__(
  prefix, 'qapi-introspect',
  ' * QAPI/QMP schema introspection', __doc__)
  self._unmask = unmask
-self._schema = None
-self._trees = []
-self._used_types = []
-self._name_map = {}
+self._schema: Optional[QAPISchema] = None
+self._trees: List[TreeNode] = []
+self._used_types: List[QAPISchemaType] = []
+self._name_map: Dict[str, str] = {}
  self._genc.add(mcgen('''
  #include "qemu/osdep.h"
  #include "%(prefix)sqapi-introspect.h"
@@ -107,10 +140,10 @@ class 
QAPISchemaGenIntrospectVisitor(QAPISchemaMonolithicCVisitor):
  ''',
   prefix=prefix))
  
-def visit_begin(self, schema):

+def visit_begin(self, schema: QAPISchema) -> None:
  self._schema = schema
  
-def visit_end(self):

+def visit_end(self) -> None:
  # visit the types that are actually used
  for typ in self._used_types:
  typ.visit(self)
@@ -132,18 +165,18 @@ const QLitObject %(c_name)s = %(c_string)s;
  self._used_types = []
 

Re: [PATCH v8 3/7] block: declare some coroutine functions in block/coroutines.h

2020-09-23 Thread Eric Blake

On 9/15/20 11:44 AM, Vladimir Sementsov-Ogievskiy wrote:

We are going to keep coroutine-wrappers code (structure-packing
parameters, BDRV_POLL wrapper functions) in separate auto-generated
files. So, we'll need a header with declaration of original _co_
functions, for those which are static now. As well, we'll need
declarations for wrapper functions. Do these declarations now, as a
preparation step.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Eric Blake 
---



+++ b/block/coroutines.h



+int coroutine_fn bdrv_co_check(BlockDriverState *bs,
+   BdrvCheckResult *res, BdrvCheckMode fix);
+int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp);
+
+int coroutine_fn
+bdrv_co_prwv(BdrvChild *child, int64_t offset, QEMUIOVector *qiov,
+ bool is_write, BdrvRequestFlags flags);


Inconsistent on whether the function name is in column 1 or after the 
return type. But we aren't consistent elsewhre, so I won't bother 
changing it.


R-b still stands

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v2 31/38] qapi/introspect.py: add _gen_features helper

2020-09-23 Thread John Snow

On 9/23/20 12:35 PM, Eduardo Habkost wrote:

I believe these two lines above should be removed, as suggested
in patch 30, but let's ignore that for now.



Yup, headed there.


-if features:
-obj['features'] = [(f.name, Extra(None, f.ifcond)) for f in features]

I can't say I understand completely why moving these two lines
outside _make_tree() is useful, but if it makes the cleanup work
you did easier, I trust this is the right thing to do.  The
changes look correct.


The basic premise is:

Why pass information you want to add to obj['features'] to a function to 
make that assignment, when you could just perform that assignment yourself?


Otherwise, _make_tree, which accepts any arbitrary object (not just 
dicts!) has to interrogate its arguments to make sure you gave it a dict 
when you give it a features argument.


Type-wise, it's cleaner to perform this transformation when we KNOW we 
have an object than it is to defer to a more abstracted function and 
assert/downcast back to more specific types.





Re: [PATCH v2 30/38] qapi/introspect.py: Add a typed 'extra' structure

2020-09-23 Thread John Snow

On 9/23/20 12:13 PM, Eduardo Habkost wrote:

On Tue, Sep 22, 2020 at 05:00:53PM -0400, John Snow wrote:

Typing arbitrarily shaped dicts with mypy is difficult prior to Python
3.8; using explicit structures is nicer.

Since we always define an Extra type now, the return type of _make_tree
simplifies and always returns the tuple.

Signed-off-by: John Snow 
---
  scripts/qapi/introspect.py | 31 +++
  1 file changed, 19 insertions(+), 12 deletions(-)



Here I'm confused by both the original code and the new code.

I will try to review as a refactoring of existing code, but I'll
have suggestions for follow ups:


diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index b036fcf9ce..41ca8afc67 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -10,6 +10,8 @@
  See the COPYING file in the top-level directory.
  """
  
+from typing import (NamedTuple, Optional, Sequence)

+
  from .common import (
  c_name,
  gen_endif,
@@ -21,16 +23,21 @@
   QAPISchemaType)
  
  
-def _make_tree(obj, ifcond, features, extra=None):

-if extra is None:
-extra = {}
-if ifcond:
-extra['if'] = ifcond
+class Extra(NamedTuple):
+"""
+Extra contains data that isn't intended for output by introspection.
+"""
+comment: Optional[str] = None
+ifcond: Sequence[str] = tuple()
+
+
+def _make_tree(obj, ifcond, features,
+   extra: Optional[Extra] = None):
+comment = extra.comment if extra else None
+extra = Extra(comment, ifcond)


Here we have one big difference: now `extra` is being recreated,
and all fields except `extra.comment` are being ignored.  On the
original version, all fields in `extra` were being kept.  This
makes the existence of the `extra` argument pointless.



Yup, oops.


If you are going through the trouble of changing the type of the
4rd argument to _make_tree(), this seems more obvious:



Yes, agree. I came up with something similar after talking to you this 
morning.



   diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
   index 41ca8afc672..c62af94c9ad 100644
   --- a/scripts/qapi/introspect.py
   +++ b/scripts/qapi/introspect.py
   @@ -32,8 +32,7 @@ class Extra(NamedTuple):


def _make_tree(obj, ifcond, features,

   -   extra: Optional[Extra] = None):
   -comment = extra.comment if extra else None
   +   comment: Optional[str] = None):
extra = Extra(comment, ifcond)
if features:
obj['features'] = [(f.name, Extra(None, f.ifcond)) for f in 
features]
   @@ -170,16 +169,16 @@ const QLitObject %(c_name)s = %(c_string)s;
return self._name(typ.name)

def _gen_tree(self, name, mtype, obj, ifcond, features):

   -extra = None
   +comment = None
if mtype not in ('command', 'event', 'builtin', 'array'):
if not self._unmask:
# Output a comment to make it easy to map masked names
# back to the source when reading the generated output.
   -extra = Extra(comment=f'"{self._name(name)}" = {name}')
   +comment = f'"{self._name(name)}" = {name}'
name = self._name(name)
obj['name'] = name
obj['meta-type'] = mtype
   -self._trees.append(_make_tree(obj, ifcond, features, extra))
   +self._trees.append(_make_tree(obj, ifcond, features, comment))

def _gen_member(self, member):

obj = {'name': member.name, 'type': self._use_type(member.type)}

I understand you're trying to just make minimal refactoring, and I
don't think this should block your cleanup series.  So:

Reviewed-by: Eduardo Habkost 



I appreciate the benefit-of-the-doubt, but I think this change is worth 
making while we're here.





  if features:
-obj['features'] = [(f.name, {'if': f.ifcond}) for f in features]
-if extra:
-return (obj, extra)
-return obj
+obj['features'] = [(f.name, Extra(None, f.ifcond)) for f in features]
+return (obj, extra)
  
  
  def _tree_to_qlit(obj, level=0, suppress_first_indent=False):

@@ -40,8 +47,8 @@ def indent(level):
  
  if isinstance(obj, tuple):

  ifobj, extra = obj
-ifcond = extra.get('if')
-comment = extra.get('comment')
+ifcond = extra.ifcond
+comment = extra.comment
  ret = ''
  if comment:
  ret += indent(level) + '/* %s */\n' % comment
@@ -168,7 +175,7 @@ def _gen_tree(self, name, mtype, obj, ifcond, features):
  if not self._unmask:
  # Output a comment to make it easy to map masked names
  # back to the source when reading the generated output.
-extra = {'comment': '"%s" = %s' % (self._name(name), name)}
+extra = Extra(comment=f'"{self._name(name)}" = {name}')
  name 

Re: [PATCH v2 14/38] qapi/common.py: Convert comments into docstrings, and elaborate

2020-09-23 Thread John Snow

On 9/23/20 3:38 PM, Cleber Rosa wrote:

On Tue, Sep 22, 2020 at 05:00:37PM -0400, John Snow wrote:

As docstrings, they'll show up in documentation and IDE help.

Signed-off-by: John Snow 
---
  scripts/qapi/common.py | 51 ++
  1 file changed, 37 insertions(+), 14 deletions(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 0ce4a107e6..730283722a 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -20,10 +20,18 @@
  _C_NAME_TRANS = str.maketrans('.-', '__')
  
  
-# ENUMName -> ENUM_NAME, EnumName1 -> ENUM_NAME1

-# ENUM_NAME -> ENUM_NAME, ENUM_NAME1 -> ENUM_NAME1, ENUM_Name2 -> ENUM_NAME2
-# ENUM24_Name -> ENUM24_NAME
  def camel_to_upper(value: str) -> str:
+"""
+Converts CamelCase to CAMEL_CASE.
+
+Examples:
+  ENUMName -> ENUM_NAME
+  EnumName1 -> ENUM_NAME1
+  ENUM_NAME -> ENUM_NAME
+  ENUM_NAME1 -> ENUM_NAME1
+  ENUM_Name2 -> ENUM_NAME2
+  ENUM24_Name -> ENUM24_NAME
+"""
  c_fun_str = c_name(value, False)
  if value.isupper():
  return c_fun_str
@@ -45,21 +53,33 @@ def camel_to_upper(value: str) -> str:
  def c_enum_const(type_name: str,
   const_name: str,
   prefix: Optional[str] = None) -> str:
+"""
+Generate a C enumeration constant name.
+
+:param type_name: The name of the enumeration.
+:param const_name: The name of this constant.
+:param prefix: Optional, prefix that overrides the type_name.
+"""
  if prefix is not None:
  type_name = prefix
  return camel_to_upper(type_name) + '_' + c_name(const_name, False).upper()
  
  
-# Map @name to a valid C identifier.

-# If @protect, avoid returning certain ticklish identifiers (like
-# C keywords) by prepending 'q_'.
-#
-# Used for converting 'name' from a 'name':'type' qapi definition
-# into a generated struct member, as well as converting type names
-# into substrings of a generated C function name.
-# '__a.b_c' -> '__a_b_c', 'x-foo' -> 'x_foo'
-# protect=True: 'int' -> 'q_int'; protect=False: 'int' -> 'int'
  def c_name(name: str, protect: bool = True) -> str:
+"""
+Map `name` to a valid C identifier.
+
+Used for converting 'name' from a 'name':'type' qapi definition
+into a generated struct member, as well as converting type names
+into substrings of a generated C function name.
+
+'__a.b_c' -> '__a_b_c', 'x-foo' -> 'x_foo'
+protect=True: 'int' -> 'q_int'; protect=False: 'int' -> 'int'
+
+:param name: The name to map.
+:param protect: If true, avoid returning certain ticklish identifiers
+(like C keywords) by prepending ``q_``.
+"""
  # ANSI X3J11/88-090, 3.1.1
  c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue',
   'default', 'do', 'double', 'else', 'enum', 'extern',
@@ -134,9 +154,12 @@ def decrease(self, amount: int = 4) -> int:
  indent = Indentation()
  
  
-# Generate @code with @kwds interpolated.

-# Obey indent, and strip EATSPACE.
  def cgen(code: str, **kwds: object) -> str:
+"""
+Generate `code` with `kwds` interpolated.
+
+Obey `indent`, and strip `EATSPACE`.
+"""


This probably won't help on IDEs (never checked any), but sphinx will
let you do:

"""
Generate `code` with `kwds` interpolated.

Obey `indent`, and strip :data:`EATSPACE`.
"""

I'm not sure that a maximum level of docstring "sphinxzation" is the
goal here, though.

Reviewed-by: Cleber Rosa 



It isn't yet, but I intend to address that when I remove 
missing-docstring from pylint exemptions. Do I need :data: if I set the 
default role to 'any'?


I'll probably try to enable sphinx at that time (and put the docs in a 
devel/python manual?) and worry about the formatting at that point.


--js




Re: [PATCH] load_elf: Remove unused address variables from callers

2020-09-23 Thread BALATON Zoltan via

On Wed, 23 Sep 2020, BALATON Zoltan wrote:

On Tue, 7 Jul 2020, BALATON Zoltan wrote:

On Tue, 7 Jul 2020, Alistair Francis wrote:

On Sun, Jul 5, 2020 at 10:41 AM BALATON Zoltan  wrote:

Several callers of load_elf() pass pointers for lowaddr and highaddr
parameters which are then not used for anything. This may stem from a
misunderstanding that load_elf need a value here but in fact it can
take NULL to ignore these values. Remove such unused variables and
pass NULL instead from callers that don't need these.

Signed-off-by: BALATON Zoltan 


Reviewed-by: Alistair Francis 


So this got a few review and acked by but since it touches multiple parts 
who will actually send pull or merge it? I'd like to make sure this won't 
miss the freeze deadline just because everybody thinks this should go in 
via some other maintainer. What's the best way for this? Trivial 
maintainers or Peter should handle such patches?


Ping? Could someone please queue this patch? It still seems to apply cleanly.


Forgot to include the link to the original patch:

http://patchwork.ozlabs.org/project/qemu-devel/patch/20200705174020.bdd01746...@zero.eik.bme.hu/


Regards,
BALATON Zoltan


---
 hw/alpha/dp264.c   |  8 
 hw/arm/armv7m.c|  4 +---
 hw/cris/boot.c |  4 ++--
 hw/microblaze/boot.c   |  4 ++--
 hw/mips/fuloong2e.c|  8 
 hw/moxie/moxiesim.c|  4 ++--
 hw/nios2/boot.c|  4 ++--
 hw/ppc/mac_newworld.c  |  6 ++
 hw/ppc/mac_oldworld.c  |  6 ++
 hw/ppc/ppc440_bamboo.c |  9 +++--
 hw/ppc/sam460ex.c  | 12 +---
 hw/ppc/spapr.c | 11 ---
 hw/ppc/virtex_ml507.c  |  4 ++--
 hw/riscv/boot.c|  8 
 hw/xtensa/sim.c|  3 +--
 hw/xtensa/xtfpga.c |  3 +--
 16 files changed, 41 insertions(+), 57 deletions(-)

diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index f7751b18f6..4d24518d1d 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -62,8 +62,8 @@ static void clipper_init(MachineState *machine)
 qemu_irq rtc_irq;
 long size, i;
 char *palcode_filename;
-uint64_t palcode_entry, palcode_low, palcode_high;
-uint64_t kernel_entry, kernel_low, kernel_high;
+uint64_t palcode_entry;
+uint64_t kernel_entry, kernel_low;
 unsigned int smp_cpus = machine->smp.cpus;

 /* Create up to 4 cpus.  */
@@ -113,7 +113,7 @@ static void clipper_init(MachineState *machine)
 exit(1);
 }
 size = load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys,
-NULL, _entry, _low, _high, 
NULL,

+NULL, _entry, NULL, NULL, NULL,
 0, EM_ALPHA, 0, 0);
 if (size < 0) {
 error_report("could not load palcode '%s'", palcode_filename);
@@ -132,7 +132,7 @@ static void clipper_init(MachineState *machine)
 uint64_t param_offset;

 size = load_elf(kernel_filename, NULL, 
cpu_alpha_superpage_to_phys,
-NULL, _entry, _low, _high, 
NULL,

+NULL, _entry, _low, NULL, NULL,
 0, EM_ALPHA, 0, 0);
 if (size < 0) {
 error_report("could not load kernel '%s'", kernel_filename);
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 3308211e9c..92f859d760 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -309,7 +309,6 @@ void armv7m_load_kernel(ARMCPU *cpu, const char 
*kernel_filename, int mem_size)

 {
 int image_size;
 uint64_t entry;
-uint64_t lowaddr;
 int big_endian;
 AddressSpace *as;
 int asidx;
@@ -330,12 +329,11 @@ void armv7m_load_kernel(ARMCPU *cpu, const char 
*kernel_filename, int mem_size)


 if (kernel_filename) {
 image_size = load_elf_as(kernel_filename, NULL, NULL, NULL,
- , , NULL,
+ , NULL, NULL,
  NULL, big_endian, EM_ARM, 1, 0, as);
 if (image_size < 0) {
 image_size = load_image_targphys_as(kernel_filename, 0,
 mem_size, as);
-lowaddr = 0;
 }
 if (image_size < 0) {
 error_report("Could not load kernel '%s'", kernel_filename);
diff --git a/hw/cris/boot.c b/hw/cris/boot.c
index b8947bc660..aa8d2756d6 100644
--- a/hw/cris/boot.c
+++ b/hw/cris/boot.c
@@ -67,7 +67,7 @@ static uint64_t translate_kernel_address(void *opaque, 
uint64_t addr)

 void cris_load_image(CRISCPU *cpu, struct cris_load_info *li)
 {
 CPUCRISState *env = >env;
-uint64_t entry, high;
+uint64_t entry;
 int kcmdline_len;
 int image_size;

@@ -76,7 +76,7 @@ void cris_load_image(CRISCPU *cpu, struct 
cris_load_info *li)

devboard SDK.  */
 image_size = load_elf(li->image_filename, NULL,
   translate_kernel_address, NULL,
-  , NULL, , NULL, 0, EM_CRIS, 0, 0);
+  , NULL, NULL, NULL, 0, EM_CRIS, 0, 0);
 li->entry = entry;
 

Re: [PATCH] load_elf: Remove unused address variables from callers

2020-09-23 Thread BALATON Zoltan via

On Tue, 7 Jul 2020, BALATON Zoltan wrote:

On Tue, 7 Jul 2020, Alistair Francis wrote:

On Sun, Jul 5, 2020 at 10:41 AM BALATON Zoltan  wrote:

Several callers of load_elf() pass pointers for lowaddr and highaddr
parameters which are then not used for anything. This may stem from a
misunderstanding that load_elf need a value here but in fact it can
take NULL to ignore these values. Remove such unused variables and
pass NULL instead from callers that don't need these.

Signed-off-by: BALATON Zoltan 


Reviewed-by: Alistair Francis 


So this got a few review and acked by but since it touches multiple parts who 
will actually send pull or merge it? I'd like to make sure this won't miss 
the freeze deadline just because everybody thinks this should go in via some 
other maintainer. What's the best way for this? Trivial maintainers or Peter 
should handle such patches?


Ping? Could someone please queue this patch? It still seems to apply 
cleanly.


Regards,
BALATON Zoltan


---
 hw/alpha/dp264.c   |  8 
 hw/arm/armv7m.c|  4 +---
 hw/cris/boot.c |  4 ++--
 hw/microblaze/boot.c   |  4 ++--
 hw/mips/fuloong2e.c|  8 
 hw/moxie/moxiesim.c|  4 ++--
 hw/nios2/boot.c|  4 ++--
 hw/ppc/mac_newworld.c  |  6 ++
 hw/ppc/mac_oldworld.c  |  6 ++
 hw/ppc/ppc440_bamboo.c |  9 +++--
 hw/ppc/sam460ex.c  | 12 +---
 hw/ppc/spapr.c | 11 ---
 hw/ppc/virtex_ml507.c  |  4 ++--
 hw/riscv/boot.c|  8 
 hw/xtensa/sim.c|  3 +--
 hw/xtensa/xtfpga.c |  3 +--
 16 files changed, 41 insertions(+), 57 deletions(-)

diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index f7751b18f6..4d24518d1d 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -62,8 +62,8 @@ static void clipper_init(MachineState *machine)
 qemu_irq rtc_irq;
 long size, i;
 char *palcode_filename;
-uint64_t palcode_entry, palcode_low, palcode_high;
-uint64_t kernel_entry, kernel_low, kernel_high;
+uint64_t palcode_entry;
+uint64_t kernel_entry, kernel_low;
 unsigned int smp_cpus = machine->smp.cpus;

 /* Create up to 4 cpus.  */
@@ -113,7 +113,7 @@ static void clipper_init(MachineState *machine)
 exit(1);
 }
 size = load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys,
-NULL, _entry, _low, _high, 
NULL,

+NULL, _entry, NULL, NULL, NULL,
 0, EM_ALPHA, 0, 0);
 if (size < 0) {
 error_report("could not load palcode '%s'", palcode_filename);
@@ -132,7 +132,7 @@ static void clipper_init(MachineState *machine)
 uint64_t param_offset;

 size = load_elf(kernel_filename, NULL, 
cpu_alpha_superpage_to_phys,
-NULL, _entry, _low, _high, 
NULL,

+NULL, _entry, _low, NULL, NULL,
 0, EM_ALPHA, 0, 0);
 if (size < 0) {
 error_report("could not load kernel '%s'", kernel_filename);
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 3308211e9c..92f859d760 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -309,7 +309,6 @@ void armv7m_load_kernel(ARMCPU *cpu, const char 
*kernel_filename, int mem_size)

 {
 int image_size;
 uint64_t entry;
-uint64_t lowaddr;
 int big_endian;
 AddressSpace *as;
 int asidx;
@@ -330,12 +329,11 @@ void armv7m_load_kernel(ARMCPU *cpu, const char 
*kernel_filename, int mem_size)


 if (kernel_filename) {
 image_size = load_elf_as(kernel_filename, NULL, NULL, NULL,
- , , NULL,
+ , NULL, NULL,
  NULL, big_endian, EM_ARM, 1, 0, as);
 if (image_size < 0) {
 image_size = load_image_targphys_as(kernel_filename, 0,
 mem_size, as);
-lowaddr = 0;
 }
 if (image_size < 0) {
 error_report("Could not load kernel '%s'", kernel_filename);
diff --git a/hw/cris/boot.c b/hw/cris/boot.c
index b8947bc660..aa8d2756d6 100644
--- a/hw/cris/boot.c
+++ b/hw/cris/boot.c
@@ -67,7 +67,7 @@ static uint64_t translate_kernel_address(void *opaque, 
uint64_t addr)

 void cris_load_image(CRISCPU *cpu, struct cris_load_info *li)
 {
 CPUCRISState *env = >env;
-uint64_t entry, high;
+uint64_t entry;
 int kcmdline_len;
 int image_size;

@@ -76,7 +76,7 @@ void cris_load_image(CRISCPU *cpu, struct cris_load_info 
*li)

devboard SDK.  */
 image_size = load_elf(li->image_filename, NULL,
   translate_kernel_address, NULL,
-  , NULL, , NULL, 0, EM_CRIS, 0, 0);
+  , NULL, NULL, NULL, 0, EM_CRIS, 0, 0);
 li->entry = entry;
 if (image_size < 0) {
 /* Takes a kimage from the axis devboard SDK.  */
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index 925e3f7c9d..8ad3c27f2c 100644
--- 

Re: [PATCH 14/14] qapi/doc.py: enable pylint checks

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:18:02PM -0400, John Snow wrote:
> Signed-off-by: John Snow 

Tested-by: Eduardo Habkost 
Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 13/14] qapi/doc.py: Assert type of object variant

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:18:01PM -0400, John Snow wrote:
> Objects may have variants, but those variants must themselves be
> objects. This is difficult to express with our current type system and
> hierarchy, so instead pepper in an assertion.
> 
> Note: These assertions don't appear to be useful yet because schema.py
> is not yet typed. Once it is, these assertions will matter.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 12/14] qapi/doc.py: Assert tag member is Enum type

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:18:00PM -0400, John Snow wrote:
> The type system can't quite express this constraint natively: members
> can envelop any type -- but tag_members may only ever envelop an
> enumerated type.
> 
> For now, shrug and add an assertion.
> 
> Note: These assertions don't appear to be useful yet because schema.py
> is not yet typed. Once it is, these assertions will matter.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 11/14] qapi/doc.py: Don't use private attributes of QAPIGen property

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:17:59PM -0400, John Snow wrote:
> Use the new __bool__ method to do the same without exposing the private
> attribute.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 10/14] qapi/gen.py: Add __bool__ dunder method to QAPIGen

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:17:58PM -0400, John Snow wrote:
> Falseish when there is no body or preamble; Trueish when there is.
> Header and footer are excluded for now, because they are assumed to be
> dynamic and always present.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 09/14] qapi/doc.py: Remove one-letter variables

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:17:57PM -0400, John Snow wrote:
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 06/14] qapi/doc.py: Add type hint annotations

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:17:54PM -0400, John Snow wrote:
> Annotations do not change runtime behavior.
> This commit *only* adds annotations.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH v4 1/2] qemu/atomic: Update coding style to make checkpatch.pl happier

2020-09-23 Thread Carlo Marcelo Arenas Belón
will be also nice to squash the following on top for a complete clean
checkpatch version, as the original patch introduces at least 1 issue

Carlo
--- >8 ---
Subject: fixup! [PATCH 1/2] qemu/atomic.h: rename atomic_ to qatomic_

fixes:

ERROR: Macros with multiple statements should be enclosed in a do - while loop
+#define qatomic_rcu_read__nocheck(ptr, valptr)   \
+__atomic_load(ptr, valptr, __ATOMIC_RELAXED);\
 smp_read_barrier_depends();

false positive:

ERROR: memory barrier without comment
+#define qatomic_xchg(ptr, i)(smp_mb(), __sync_lock_test_and_set(ptr, i))

Signed-off-by: Carlo Marcelo Arenas Belón 
---
 include/qemu/atomic.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
index 87b85f9f6d..be47e083be 100644
--- a/include/qemu/atomic.h
+++ b/include/qemu/atomic.h
@@ -149,9 +149,10 @@
 #define qatomic_rcu_read__nocheck(ptr, valptr)   \
 __atomic_load(ptr, valptr, __ATOMIC_CONSUME);
 #else
-#define qatomic_rcu_read__nocheck(ptr, valptr)   \
+#define qatomic_rcu_read__nocheck(ptr, valptr) do {  \
 __atomic_load(ptr, valptr, __ATOMIC_RELAXED);\
-smp_read_barrier_depends();
+smp_read_barrier_depends();  \
+} while (0)
 #endif
 
 #define qatomic_rcu_read(ptr)  \
-- 
2.28.0.681.g6f77f65b4e




Re: [PATCH 05/14] qapi/doc.py: Assert no suffix given for enum members

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:17:53PM -0400, John Snow wrote:
> We don't do anything with this argument. If something shows up here,
> something wrong has happened.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 04/14] qapi/doc.py: assert correct types in member_func callbacks

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:17:52PM -0400, John Snow wrote:
> These each take a specific subtype; assert that they got that correct
> subtype.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 07/14] qapi/doc.py: enable mypy checks

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:17:55PM -0400, John Snow wrote:
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 03/14] qapi/doc.py: Add assertion on section.member

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:17:51PM -0400, John Snow wrote:
> Similarly to other cases, we lack the power at the moment to express
> that a specific member is constrained to a certain containing type. Add
> an assertion before we use properties specific to that type.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 02/14] qapi/doc.py: avoid unnecessary keyword arguments

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:17:50PM -0400, John Snow wrote:
> Keyword Callables are hard to type in Python 3.6, avoid them if there's
> no urgent need to use them.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 01/14] qapi/doc.py: stash long temporary locals in named locals

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:17:49PM -0400, John Snow wrote:
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PULL v3 00/15] virtio,pc,acpi: fixes, tests

2020-09-23 Thread Michael S. Tsirkin
Peter, you said you see issues on some systems.
I pushed a tag: 
git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream_test
which drops some patches I suspect.
If that helps, pls let me know.


On Mon, Sep 21, 2020 at 08:31:35AM -0400, Michael S. Tsirkin wrote:
> On Mon, Sep 21, 2020 at 07:44:42PM +0800, Li Qiang wrote:
> > Michael S. Tsirkin  于2020年9月21日周一 下午7:30写道:
> > >
> > > The following changes since commit 
> > > 053a4177817db307ec854356e95b5b350800a216:
> > >
> > >   Merge remote-tracking branch 
> > > 'remotes/philmd-gitlab/tags/fw_cfg-20200918' into staging (2020-09-18 
> > > 16:34:26 +0100)
> > >
> > > are available in the Git repository at:
> > >
> > >   git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
> > >
> > > for you to fetch changes up to acbdbd5db6dab68534702987a487360fd8ae02b7:
> > >
> > >   virtio-iommu-pci: force virtio version 1 (2020-09-21 06:14:46 -0400)
> > >
> > > 
> > > virtio,pc,acpi: fixes, tests
> > >
> > > Fixes and tests all over the place.
> > > Batch iommu updates for vdpa.
> > > Removal of deprecated cpu hotplug commands.
> > >
> > > Signed-off-by: Michael S. Tsirkin 
> > >
> > > 
> > > David Hildenbrand (1):
> > >   pc: fix auto_enable_numa_with_memhp/auto_enable_numa_with_memdev 
> > > for the 5.0 machine
> > >
> > > Dima Stepanov (7):
> > >   vhost: recheck dev state in the vhost_migration_log routine
> > >   vhost: check queue state in the vhost_dev_set_log routine
> > >   tests/qtest/vhost-user-test: prepare the tests for adding new dev 
> > > class
> > >   tests/qtest/libqos/virtio-blk: add support for vhost-user-blk
> > >   tests/qtest/vhost-user-test: add support for the vhost-user-blk 
> > > device
> > >   tests/qtest/vhost-user-test: add migrate_reconnect test
> > >   tests/qtest/vhost-user-test: enable the reconnect tests
> > >
> > > Eric Auger (2):
> > >   virtio-iommu: Check gtrees are non null before destroying them
> > >   virtio-iommu-pci: force virtio version 1
> > >
> > > Igor Mammedov (1):
> > >   cphp: remove deprecated cpu-add command(s)
> > >
> > > Jason Wang (3):
> > >   linux headers: sync to 5.9-rc4
> > >   vhost: switch to use IOTLB v2 format
> > >   vhost-vdpa: batch updating IOTLB mappings
> > >
> > > Li Qiang (1):
> > >   virtio-mem: detach the element from the virtqueue when error occurs
> > 
> > Hello Michael,
> > It seems you lost the virtio-pmem patch.
> > 
> > https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg02639.html
> 
> That's because I was never copied. Can you repost with all tags and Cc
> me?
> Subject can be PATCH repost.
> 
> > Anyway, it can be queued in the next pr.
> > 
> > Thanks,
> > Li Qiang




[PATCH] docs: Better mention of qemu-img amend limitations

2020-09-23 Thread Eric Blake
Missed during merge resolution of commit bc5ee6da71.

Signed-off-by: Eric Blake 
---
 docs/tools/qemu-img.rst | 4 
 1 file changed, 4 insertions(+)

diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
index c35bd6482203..2b5891b54db7 100644
--- a/docs/tools/qemu-img.rst
+++ b/docs/tools/qemu-img.rst
@@ -265,6 +265,10 @@ Command description:
   --force allows some unsafe operations. Currently for -f luks, it allows to
   erase the last encryption key, and to overwrite an active encryption key.

+  The set of options that can be amended are dependent on the image
+  format, but note that amending the backing chain relationship should
+  instead be performed with ``qemu-img rebase``.
+
 .. option:: bench [-c COUNT] [-d DEPTH] [-f FMT] 
[--flush-interval=FLUSH_INTERVAL] [-i AIO] [-n] [--no-drain] [-o OFFSET] 
[--pattern=PATTERN] [-q] [-s BUFFER_SIZE] [-S STEP_SIZE] [-t CACHE] [-w] [-U] 
FILENAME

   Run a simple sequential I/O benchmark on the specified image. If ``-w`` is
-- 
2.28.0




Re: [PATCH 16/16] qapi/expr.py: Use an expression checker dispatch table

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:13:13PM -0400, John Snow wrote:
> This enforces a type signature against all of the top-level expression
> check routines without necessarily needing to create some
> overcomplicated class hierarchy for them.
> 
> Signed-off-by: John Snow 
> ---
>  scripts/qapi/expr.py | 69 ++--
>  1 file changed, 35 insertions(+), 34 deletions(-)
> 
> diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
> index 74b2681ef8..cfd342aa04 100644
> --- a/scripts/qapi/expr.py
> +++ b/scripts/qapi/expr.py
> @@ -31,8 +31,11 @@
>  structures and contextual semantic validation.
>  """
>  
> +from enum import Enum
>  import re
>  from typing import (
> +Callable,
> +Dict,
>  Iterable,
>  List,
>  MutableMapping,
> @@ -494,6 +497,26 @@ def check_event(expr: Expression, info: QAPISourceInfo) 
> -> None:
>  check_type(args, info, "'data'", allow_dict=not boxed)
>  
>  
> +class ExpressionType(str, Enum):
> +INCLUDE = 'include'
> +ENUM = 'enum'
> +UNION = 'union'
> +ALTERNATE = 'alternate'
> +STRUCT = 'struct'
> +COMMAND = 'command'
> +EVENT = 'event'
> +
> +
> +_CHECK_FN: Dict[str, Callable[[Expression, QAPISourceInfo], None]] = {
> +'enum': check_enum,
> +'union': check_union,
> +'alternate': check_alternate,
> +'struct': check_struct,
> +'command': check_command,
> +'event': check_event,
> +}
> +
> +
>  def check_exprs(exprs: List[_JSObject]) -> List[_JSObject]:
>  """
>  Validate and normalize a list of parsed QAPI schema expressions. [RW]
> @@ -519,28 +542,20 @@ def check_exprs(exprs: List[_JSObject]) -> 
> List[_JSObject]:
>  assert tmp is None or isinstance(tmp, QAPIDoc)
>  doc: Optional[QAPIDoc] = tmp
>  
> -if 'include' in expr:
> -continue
> -
> -if 'enum' in expr:
> -meta = 'enum'
> -elif 'union' in expr:
> -meta = 'union'
> -elif 'alternate' in expr:
> -meta = 'alternate'
> -elif 'struct' in expr:
> -meta = 'struct'
> -elif 'command' in expr:
> -meta = 'command'
> -elif 'event' in expr:
> -meta = 'event'
> +for kind in ExpressionType:
> +if kind in expr:
> +meta = kind

I see lots of meta.value expressions below.  Maybe setting
  meta = kind.value
will make the code more readable?

I don't think this should block an obvious improvement to the
code, so:

Reviewed-by: Eduardo Habkost 

> +break
>  else:
>  raise QAPISemError(info, "expression is missing metatype")
>  
> +if meta == ExpressionType.INCLUDE:
> +continue
> +
>  name = cast(str, expr[meta])  # asserted right below:
> -check_name_is_str(name, info, "'%s'" % meta)
> -info.set_defn(meta, name)
> -check_defn_name_str(name, info, meta)
> +check_name_is_str(name, info, "'%s'" % meta.value)
> +info.set_defn(meta.value, name)
> +check_defn_name_str(name, info, meta.value)
>  
>  if doc:
>  if doc.symbol != name:
> @@ -551,22 +566,8 @@ def check_exprs(exprs: List[_JSObject]) -> 
> List[_JSObject]:
>  raise QAPISemError(info,
> "documentation comment required")
>  
> -if meta == 'enum':
> -check_enum(expr, info)
> -elif meta == 'union':
> -check_union(expr, info)
> -elif meta == 'alternate':
> -check_alternate(expr, info)
> -elif meta == 'struct':
> -check_struct(expr, info)
> -elif meta == 'command':
> -check_command(expr, info)
> -elif meta == 'event':
> -check_event(expr, info)
> -else:
> -assert False, 'unexpected meta type'
> -
> -check_if(expr, info, meta)
> +_CHECK_FN[meta](expr, info)
> +check_if(expr, info, meta.value)
>  check_features(expr.get('features'), info)
>  check_flags(expr, info)
>  
> -- 
> 2.26.2
> 

-- 
Eduardo




Re: [PULL 00/13] Block patches

2020-09-23 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200923161031.69474-1-stefa...@redhat.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20200923161031.69474-1-stefa...@redhat.com
Subject: [PULL 00/13] Block patches

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

From https://github.com/patchew-project/qemu
 * [new tag] patchew/20200923161031.69474-1-stefa...@redhat.com -> 
patchew/20200923161031.69474-1-stefa...@redhat.com
Switched to a new branch 'test'
4bf3742 qemu/atomic.h: rename atomic_ to qatomic_
8cecbb3 tests: add test-fdmon-epoll
8df4df8 fdmon-poll: reset npfd when upgrading to fdmon-epoll
825386c gitmodules: add qemu.org vbootrom submodule
5cae6f8 gitmodules: switch to qemu.org meson mirror
98349d3 gitmodules: switch to qemu.org qboot mirror
5f9d298 docs/system: clarify deprecation schedule
b431c3a virtio-crypto: don't modify elem->in/out_sg
c1f9691 virtio-blk: undo destructive iov_discard_*() operations
4182d4f util/iov: add iov_discard_undo()
a59a839 virtio: add vhost-user-fs-ccw device
0d23a8c libvhost-user: handle endianness as mandated by the spec
3167d81 MAINTAINERS: add Stefan Hajnoczi as block/nvme.c maintainer

=== OUTPUT BEGIN ===
1/13 Checking commit 3167d818e62a (MAINTAINERS: add Stefan Hajnoczi as 
block/nvme.c maintainer)
2/13 Checking commit 0d23a8ccd2a9 (libvhost-user: handle endianness as mandated 
by the spec)
WARNING: line over 80 characters
#53: FILE: contrib/libvhost-user/libvhost-user.c:548:
+vu_panic(dev, "virtio legacy devices aren't supported by 
libvhost-user");

total: 0 errors, 1 warnings, 217 lines checked

Patch 2/13 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
3/13 Checking commit a59a839e1d76 (virtio: add vhost-user-fs-ccw device)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#28: 
new file mode 100644

total: 0 errors, 1 warnings, 82 lines checked

Patch 3/13 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
4/13 Checking commit 4182d4f76678 (util/iov: add iov_discard_undo())
5/13 Checking commit c1f96917a3f1 (virtio-blk: undo destructive iov_discard_*() 
operations)
6/13 Checking commit b431c3a4b415 (virtio-crypto: don't modify elem->in/out_sg)
7/13 Checking commit 5f9d298c71ad (docs/system: clarify deprecation schedule)
8/13 Checking commit 98349d316498 (gitmodules: switch to qemu.org qboot mirror)
9/13 Checking commit 5cae6f86bb22 (gitmodules: switch to qemu.org meson mirror)
10/13 Checking commit 825386c4f0f2 (gitmodules: add qemu.org vbootrom submodule)
11/13 Checking commit 8df4df890bf1 (fdmon-poll: reset npfd when upgrading to 
fdmon-epoll)
12/13 Checking commit 8cecbb39509f (tests: add test-fdmon-epoll)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#42: 
new file mode 100644

total: 0 errors, 1 warnings, 89 lines checked

Patch 12/13 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
13/13 Checking commit 4bf37426ff03 (qemu/atomic.h: rename atomic_ to qatomic_)
ERROR: Macros with multiple statements should be enclosed in a do - while loop
#2800: FILE: include/qemu/atomic.h:152:
+#define qatomic_rcu_read__nocheck(ptr, valptr)   \
+__atomic_load(ptr, valptr, __ATOMIC_RELAXED);\
 smp_read_barrier_depends();

ERROR: space required before that '*' (ctx:VxB)
#2945: FILE: include/qemu/atomic.h:333:
+#define qatomic_read__nocheck(p)   (*(__typeof__(*(p)) volatile*) (p))
^

ERROR: Use of volatile is usually wrong, please add a comment
#2945: FILE: include/qemu/atomic.h:333:
+#define qatomic_read__nocheck(p)   (*(__typeof__(*(p)) volatile*) (p))

ERROR: space required before that '*' (ctx:VxB)
#2946: FILE: include/qemu/atomic.h:334:
+#define qatomic_set__nocheck(p, i) ((*(__typeof__(*(p)) volatile*) (p)) = (i))
 ^

ERROR: Use of volatile is usually wrong, please add a comment
#2946: FILE: include/qemu/atomic.h:334:
+#define qatomic_set__nocheck(p, i) ((*(__typeof__(*(p)) volatile*) (p)) = (i))

ERROR: space required after that ',' (ctx:VxV)
#2951: FILE: include/qemu/atomic.h:337:
+#define qatomic_set(ptr, i) qatomic_set__nocheck(ptr,i)
 ^

ERROR: memory barrier without comment
#3023: FILE: include/qemu/atomic.h:395:
+#define qatomic_xchg(ptr, i)(smp_mb(), __sync_lock_test_and_set(ptr, i))

WARNING: Block comments use a 

Re: [PATCH 15/16] qapi/expr.py: move related checks inside check_xxx functions

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:13:12PM -0400, John Snow wrote:
> There's not a big obvious difference between the types of checks that
> happen in the main function versus the kind that happen in the
> functions. Now they're in one place for each of the main types.
> 
> As part of the move, spell out the required and optional keywords so
> they're obvious at a glance.
> 
> Signed-off-by: John Snow 
> ---
>  scripts/qapi/expr.py | 55 ++--
>  1 file changed, 33 insertions(+), 22 deletions(-)
> 
> diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
> index 69ee9e3f18..74b2681ef8 100644
> --- a/scripts/qapi/expr.py
> +++ b/scripts/qapi/expr.py
> @@ -333,6 +333,10 @@ def check_enum(expr: Expression, info: QAPISourceInfo) 
> -> None:
>  :param expr: `Expression` to validate.
>  :param info: QAPI source file information.
>  """
> +check_keys(expr, info, 'enum',
> +   required=('enum', 'data'),
> +   optional=('if', 'features', 'prefix'))
> +
>  name = expr['enum']
>  members = expr['data']
>  prefix = expr.get('prefix')
> @@ -363,6 +367,11 @@ def check_struct(expr: Expression, info: QAPISourceInfo) 
> -> None:
>  :param expr: `Expression` to validate.
>  :param info: QAPI source file information.
>  """
> +check_keys(expr, info, 'struct',
> +   required=('struct', 'data'),
> +   optional=('base', 'if', 'features'))
> +normalize_members(expr['data'])
> +
>  name = cast(str, expr['struct'])  # Asserted in check_exprs
>  members = expr['data']
>  
> @@ -377,6 +386,13 @@ def check_union(expr: Expression, info: QAPISourceInfo) 
> -> None:
>  :param expr: `Expression` to validate.
>  :param info: QAPI source file information.
>  """
> +check_keys(expr, info, 'union',
> +   required=('union', 'data'),
> +   optional=('base', 'discriminator', 'if', 'features'))
> +
> +normalize_members(expr.get('base'))
> +normalize_members(expr['data'])
> +
>  name = cast(str, expr['union'])  # Asserted in check_exprs
>  base = expr.get('base')
>  discriminator = expr.get('discriminator')
> @@ -409,6 +425,11 @@ def check_alternate(expr: Expression, info: 
> QAPISourceInfo) -> None:
>  :param expr: Expression to validate.
>  :param info: QAPI source file information.
>  """
> +check_keys(expr, info, 'alternate',
> +   required=('alternate', 'data'),
> +   optional=('if', 'features'))
> +normalize_members(expr['data'])
> +
>  members = expr['data']
>  
>  if not members:
> @@ -432,6 +453,13 @@ def check_command(expr: Expression, info: 
> QAPISourceInfo) -> None:
>  :param expr: `Expression` to validate.
>  :param info: QAPI source file information.
>  """
> +check_keys(expr, info, 'command',
> +   required=['command'],
> +   optional=('data', 'returns', 'boxed', 'if', 'features',
> + 'gen', 'success-response', 'allow-oob',
> + 'allow-preconfig'))
> +normalize_members(expr.get('data'))
> +
>  args = expr.get('data')
>  rets = expr.get('returns')
>  boxed = expr.get('boxed', False)
> @@ -453,6 +481,11 @@ def check_event(expr: Expression, info: QAPISourceInfo) 
> -> None:
>  if:   `Optional[Ifcond]`
>  features: `Optional[Features]`
>  """
> +normalize_members(expr.get('data'))
> +check_keys(expr, info, 'event',
> +   required=['event'],
> +   optional=('data', 'boxed', 'if', 'features'))

Why is the order reversed here?  The other functions call
check_keys() before normalize_members().


> +
>  args = expr.get('data')
>  boxed = expr.get('boxed', False)
>  
> @@ -519,38 +552,16 @@ def check_exprs(exprs: List[_JSObject]) -> 
> List[_JSObject]:
> "documentation comment required")
>  
>  if meta == 'enum':
> -check_keys(expr, info, meta,
> -   ['enum', 'data'], ['if', 'features', 'prefix'])
>  check_enum(expr, info)
>  elif meta == 'union':
> -check_keys(expr, info, meta,
> -   ['union', 'data'],
> -   ['base', 'discriminator', 'if', 'features'])
> -normalize_members(expr.get('base'))
> -normalize_members(expr['data'])
>  check_union(expr, info)
>  elif meta == 'alternate':
> -check_keys(expr, info, meta,
> -   ['alternate', 'data'], ['if', 'features'])
> -normalize_members(expr['data'])
>  check_alternate(expr, info)
>  elif meta == 'struct':
> -check_keys(expr, info, meta,
> -   ['struct', 'data'], ['base', 'if', 'features'])
> -normalize_members(expr['data'])
>  check_struct(expr, info)
>  elif meta == 'command':

Re: [PATCH v2 19/38] qapi/commands.py: Don't re-bind to variable of different type

2020-09-23 Thread Cleber Rosa
On Tue, Sep 22, 2020 at 05:00:42PM -0400, John Snow wrote:
> Mypy isn't a fan of rebinding a variable with a new data type.
> It's easy enough to avoid.
> 
> Signed-off-by: John Snow 

Reviewed-by: Cleber Rosa 


signature.asc
Description: PGP signature


Re: [PATCH 14/16] qapi/expr.py: Use tuples instead of lists for static data

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:13:11PM -0400, John Snow wrote:
> It is -- maybe -- possibly -- three nanoseconds faster.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH v2 18/38] qapi/events.py: Move comments into docstrings

2020-09-23 Thread Cleber Rosa
On Tue, Sep 22, 2020 at 05:00:41PM -0400, John Snow wrote:
> Signed-off-by: John Snow 

Reviewed-by: Cleber Rosa 


signature.asc
Description: PGP signature


Re: [PATCH 13/16] qapi/expr.py: Modify check_keys to accept any Iterable

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:13:10PM -0400, John Snow wrote:
> This is a very minor adjustment.
> 
> a + b is list-specific behavior, but we can accept a wider variety of
> types in a more pythonic fashion if we avoid that behavior.
> 
> Typing it this way allows callers to use things like dict.keys() and
> other iterables that are not their own discrete lists.
> 
> Including it just as a statement of practice if nothing else: It's nice
> to use the least-specific type possible as function input and use the
> most-specific type for returns.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH v2 17/38] qapi/events.py: add type hint annotations

2020-09-23 Thread Cleber Rosa
On Tue, Sep 22, 2020 at 05:00:40PM -0400, John Snow wrote:
> Annotations do not change runtime behavior.
> This commit *only* adds annotations.
> 
> Signed-off-by: John Snow 

Reviewed-by: Cleber Rosa 


signature.asc
Description: PGP signature


Re: [PATCH 12/16] qapi/expr.py: Add docstrings

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:13:09PM -0400, John Snow wrote:
> Signed-off-by: John Snow 
> ---
[...]
> @@ -160,6 +244,18 @@ def check_type(value: Optional[object],
> source: str,
> allow_array: bool = False,
> allow_dict: Union[bool, str] = False) -> None:
> +"""
> +Check the QAPI type of `value`. [RW]
> +
> +Python types of `str` or `None` are always allowed.
> +
> +:param value:   The value to check.
> +:param info:QAPI Source file information.
> +:param source:  Human readable string describing "what" the value is.
> +:param allow_array: Allow a `List[str]` of length 1,
> +which indicates an Array type.
> +:param allow_dict:  Allow a dict, treated as an anonymous type.

I was hoping the docstring would explain what happens when
allow_dict is a string.

-- 
Eduardo




Re: [PATCH 11/16] qapi/expr.py: enable pylint checks

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:13:08PM -0400, John Snow wrote:
> Signed-off-by: John Snow 

Tested-by: Eduardo Habkost 
Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH v2 16/38] qapi: establish mypy type-checking baseline

2020-09-23 Thread Cleber Rosa
On Tue, Sep 22, 2020 at 05:00:39PM -0400, John Snow wrote:
> Fix two very minor issues, and then establish a mypy type-checking
> baseline.
> 
> Like pylint, this should be run from the folder above:
> 
>  > mypy --config-file=qapi/mypy.ini qapi/

Like with pylint, let's at least document the version of mypy used.
For example, with 0.740, this fails.  With 0.782, it passes.

- Cleber.


signature.asc
Description: PGP signature


Re: [PATCH v8 7/7] block/io: refactor save/load vmstate

2020-09-23 Thread Eric Blake

On 9/15/20 11:44 AM, Vladimir Sementsov-Ogievskiy wrote:

Like for read/write in a previous commit, drop extra indirection layer,
generate directly bdrv_readv_vmstate() and bdrv_writev_vmstate().

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Eric Blake 
---
  block/coroutines.h| 10 +++
  include/block/block.h |  6 ++--
  block/io.c| 67 ++-
  3 files changed, 42 insertions(+), 41 deletions(-)

diff --git a/block/coroutines.h b/block/coroutines.h



  int coroutine_fn
-bdrv_co_rw_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos,
-   bool is_read)
+bdrv_co_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
  {
  BlockDriver *drv = bs->drv;
  int ret = -ENOTSUP;
  
+if (!drv) {

+return -ENOMEDIUM;
+}
+
  bdrv_inc_in_flight(bs);
  
-if (!drv) {

-ret = -ENOMEDIUM;
-} else if (drv->bdrv_load_vmstate) {
-if (is_read) {
-ret = drv->bdrv_load_vmstate(bs, qiov, pos);
-} else {
-ret = drv->bdrv_save_vmstate(bs, qiov, pos);
-}
+if (drv->bdrv_load_vmstate) {
+ret = drv->bdrv_load_vmstate(bs, qiov, pos);


This one makes sense;


  } else if (bs->file) {
-ret = bdrv_co_rw_vmstate(bs->file->bs, qiov, pos, is_read);
+ret = bdrv_co_readv_vmstate(bs->file->bs, qiov, pos);
  }
  
  bdrv_dec_in_flight(bs);

+
  return ret;
  }
  
-int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,

-  int64_t pos, int size)
+int coroutine_fn
+bdrv_co_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
  {
-QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, size);
-int ret;
+BlockDriver *drv = bs->drv;
+int ret = -ENOTSUP;
  
-ret = bdrv_writev_vmstate(bs, , pos);

-if (ret < 0) {
-return ret;
+if (!drv) {
+return -ENOMEDIUM;
  }
  
-return size;

-}
+bdrv_inc_in_flight(bs);
  
-int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)

-{
-return bdrv_rw_vmstate(bs, qiov, pos, false);
+if (drv->bdrv_load_vmstate) {
+ret = drv->bdrv_save_vmstate(bs, qiov, pos);


but this one looks awkward. It represents the pre-patch logic, but it 
would be nicer to check for bdrv_save_vmstate.  With that tweak, my R-b 
still stands.


I had an interesting time applying this patch due to merge conflicts 
with the new bdrv_primary_bs() changes that landed in the meantime.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH 10/16] qapi/expr.py: Remove single-letter variable

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:13:07PM -0400, John Snow wrote:
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 09/16] qapi/expr.py: rewrite check_if

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:13:06PM -0400, John Snow wrote:
> This is a only minor rewrite to address some minor style nits.  Don't
> compare against the empty list to check for the empty condition, and
> move the normalization forward to unify the check on the now-normalized
> structure.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 08/16] qapi/expr.py: add type hint annotations

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:13:05PM -0400, John Snow wrote:
> Annotations do not change runtime behavior.
> This commit *only* adds annotations.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH v2 15/38] qapi/common.py: move build_params into gen.py

2020-09-23 Thread Cleber Rosa
On Tue, Sep 22, 2020 at 05:00:38PM -0400, John Snow wrote:
> Including it in common.py creates a circular import dependency; schema
> relies on common, but common.build_params requires a type annotation
> from schema. To type this properly, it needs to be moved outside the
> cycle.
> 
> Signed-off-by: John Snow 

Reviewed-by: Cleber Rosa 


signature.asc
Description: PGP signature


Re: [PATCH 07/16] qapi/expr.py: Add casts in a few select cases

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:13:04PM -0400, John Snow wrote:
> Casts are instructions to the type checker only, they aren't "safe" and
> should probably be avoided in general. In this case, when we perform
> type checking on a nested structure, the type of each field does not
> "stick".
> 
> We don't need to assert that something is a str if we've already checked
> that it is -- use a cast instead for these cases.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 06/16] qapi/expr.py: Check type of 'data' member

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:13:03PM -0400, John Snow wrote:
> Iterating over the members of data isn't going to work if it's not some
> form of dict anyway, but for type safety, formalize it.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 05/16] qapi/expr.py: move string check upwards in check_type

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:13:02PM -0400, John Snow wrote:
> It's a simple case, shimmy the early return upwards.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 04/16] qapi/expr.py: Add assertion for union type 'check_dict'

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:13:01PM -0400, John Snow wrote:
> mypy isn't fond of allowing you to check for bool membership in a
> collection of str elements. Guard this lookup for precisely when we were
> given a name.
> 
> Signed-off-by: John Snow 
> ---
>  scripts/qapi/expr.py | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
> index f6b55a87c1..67892502e9 100644
> --- a/scripts/qapi/expr.py
> +++ b/scripts/qapi/expr.py
> @@ -166,7 +166,9 @@ def check_type(value, info, source,
>  raise QAPISemError(info,
> "%s should be an object or type name" % source)
>  
> -permit_upper = allow_dict in info.pragma.name_case_whitelist
> +permit_upper = False
> +if isinstance(allow_dict, str):
> +permit_upper = allow_dict in info.pragma.name_case_whitelist

Well, this keeps existing behavior, so:

Reviewed-by: Eduardo Habkost 

But: what exactly is the meaning of allow_dict=False,
allow_dict=True, and allow_dict being a string?


>  
>  # value is a dictionary, check that each member is okay
>  for (key, arg) in value.items():
> -- 
> 2.26.2
> 

-- 
Eduardo




Re: [PATCH 03/16] qapi/expr.py: constrain incoming expression types

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:13:00PM -0400, John Snow wrote:
> mypy does not know the types of values stored in Dicts that masquerade
> as objects. Help the type checker out by constraining the type.
> 
> Signed-off-by: John Snow 
> ---
>  scripts/qapi/expr.py | 25 ++---
>  1 file changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
> index 1872a8a3cc..f6b55a87c1 100644
> --- a/scripts/qapi/expr.py
> +++ b/scripts/qapi/expr.py
> @@ -15,9 +15,17 @@
>  # See the COPYING file in the top-level directory.
>  
>  import re
> +from typing import MutableMapping, Optional
>  
>  from .common import c_name
>  from .error import QAPISemError
> +from .parser import QAPIDoc
> +from .source import QAPISourceInfo
> +
> +
> +# Expressions in their raw form are JSON-like structures with arbitrary 
> forms.
> +# Minimally, their top-level form must be a mapping of strings to values.
> +Expression = MutableMapping[str, object]
>  
>  
>  # Names must be letters, numbers, -, and _.  They must start with letter,
> @@ -280,9 +288,20 @@ def check_event(expr, info):
>  
>  def check_exprs(exprs):
>  for expr_elem in exprs:
> -expr = expr_elem['expr']
> -info = expr_elem['info']
> -doc = expr_elem.get('doc')
> +# Expression
> +assert isinstance(expr_elem['expr'], dict)
> +expr: Expression = expr_elem['expr']
> +for key in expr.keys():
> +assert isinstance(key, str)

mypy doesn't seem to require the key type asserts, on my testing.

> +
> +# QAPISourceInfo
> +assert isinstance(expr_elem['info'], QAPISourceInfo)
> +info: QAPISourceInfo = expr_elem['info']
> +
> +# Optional[QAPIDoc]
> +tmp = expr_elem.get('doc')
> +assert tmp is None or isinstance(tmp, QAPIDoc)
> +doc: Optional[QAPIDoc] = tmp

Do you need a separate variable here?  This seems to work too:

doc = expr_elem.get('doc')
assert doc is None or isinstance(doc, QAPIDoc)

after the assert, mypy will infer the type of doc to be
Optional[QAPIDoc].

None of this should block a useful 120-patch cleanup series, so:

Reviewed-by: Eduardo Habkost 

>  
>  if 'include' in expr:
>  continue
> -- 
> 2.26.2
> 

-- 
Eduardo




[PATCH 5/6] spapr_numa: consider user input when defining associativity

2020-09-23 Thread Daniel Henrique Barboza
This patch puts all the pieces together to finally allow user
input when defining the NUMA topology of the spapr guest.

We have one more kernel restriction to handle in this patch:
the associativity array of node 0 must be filled with zeroes
[1]. The strategy below ensures that this will happen.

spapr_numa_define_associativity_domains() will read the distance
(already PAPRified) between the nodes from numa_state and determine
the appropriate NUMA level. The NUMA domains, processed in ascending
order, are going to be matched via NUMA levels, and the lowest
associativity domain value is assigned to that specific level for
both.

This will create an heuristic where the associativities of the first
nodes have higher priority and are re-used in new matches, instead of
overwriting them with a new associativity match. This is necessary
because neither QEMU, nor the pSeries kernel, supports multiple
associativity domains for each resource, meaning that we have to
decide which associativity relation is relevant.

Ultimately, all of this results in a best effort approximation for
the actual NUMA distances the user input in the command line. Given
the nature of how PAPR itself interprets NUMA distances versus the
expectations risen by how ACPI SLIT works, there might be better
algorithms but, in the end, it'll also result in another way to
approximate what the user really wanted.

To keep this commit message no longer than it already is, the next
patch will update the existing documentation in ppc-spapr-numa.rst
with more in depth details and design considerations/drawbacks.

[1] 
https://lore.kernel.org/linuxppc-dev/5e8fbea3-8faf-0951-172a-b41a2138f...@gmail.com/

Signed-off-by: Daniel Henrique Barboza 
---
 hw/ppc/spapr_numa.c | 81 -
 1 file changed, 80 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_numa.c b/hw/ppc/spapr_numa.c
index 688391278e..c84f77cda7 100644
--- a/hw/ppc/spapr_numa.c
+++ b/hw/ppc/spapr_numa.c
@@ -80,12 +80,79 @@ static void spapr_numa_PAPRify_distances(MachineState *ms)
 }
 }
 
+static uint8_t spapr_numa_get_NUMA_level(uint8_t distance)
+{
+uint8_t numa_level;
+
+switch (distance) {
+case 20:
+numa_level = 0x3;
+break;
+case 40:
+numa_level = 0x2;
+break;
+case 80:
+numa_level = 0x1;
+break;
+default:
+numa_level = 0;
+}
+
+return numa_level;
+}
+
+static void spapr_numa_define_associativity_domains(SpaprMachineState *spapr,
+MachineState *ms)
+{
+int src, dst;
+int nb_numa_nodes = ms->numa_state->num_nodes;
+NodeInfo *numa_info = ms->numa_state->nodes;
+
+for (src = 0; src < nb_numa_nodes; src++) {
+for (dst = src; dst < nb_numa_nodes; dst++) {
+/*
+ * This is how the associativity domain between A and B
+ * is calculated:
+ *
+ * - get the distance between them
+ * - get the correspondent NUMA level for this distance
+ * - the arrays were initialized with their own numa_ids,
+ * and we're calculating the distance in node_id ascending order,
+ * starting from node 0. This will have a cascade effect in the
+ * algorithm because the associativity domains that node 0 defines
+ * will be carried over to the other nodes, and node 1
+ * associativities will be carried over unless there's already a
+ * node 0 associativity assigned, and so on. This happens because
+ * we'll assign the lowest value of assoc_src and assoc_dst to be
+ * the associativity domain of both, for the given NUMA level.
+ *
+ * The PPC kernel expects the associativity domains of node 0 to
+ * be always 0, and this algorithm will grant that by default.
+ */
+uint8_t distance = numa_info[src].distance[dst];
+uint8_t n_level = spapr_numa_get_NUMA_level(distance);
+uint32_t assoc_src, assoc_dst;
+
+assoc_src = be32_to_cpu(spapr->numa_assoc_array[src][n_level]);
+assoc_dst = be32_to_cpu(spapr->numa_assoc_array[dst][n_level]);
+
+if (assoc_src < assoc_dst) {
+spapr->numa_assoc_array[dst][n_level] = cpu_to_be32(assoc_src);
+} else {
+spapr->numa_assoc_array[src][n_level] = cpu_to_be32(assoc_dst);
+}
+}
+}
+
+}
+
 void spapr_numa_associativity_init(SpaprMachineState *spapr,
MachineState *machine)
 {
 SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
 int nb_numa_nodes = machine->numa_state->num_nodes;
 int i, j, max_nodes_with_gpus;
+bool using_legacy_numa = spapr_machine_using_legacy_numa(spapr);
 
 /*
  * For all associativity arrays: first position is the size,
@@ -99,6 +166,17 @@ void 

Re: [PATCH v8 2/7] block/io: refactor coroutine wrappers

2020-09-23 Thread Eric Blake

On 9/15/20 11:44 AM, Vladimir Sementsov-Ogievskiy wrote:

Most of our coroutine wrappers already follow this convention:

We have 'coroutine_fn bdrv_co_()' as
the core function, and a wrapper 'bdrv_()' which does parameters packing and call bdrv_run_co().

The only outsiders are the bdrv_prwv_co and
bdrv_common_block_status_above wrappers. Let's refactor them to behave
as the others, it simplifies further conversion of coroutine wrappers.

This patch adds indirection layer, but it will be compensated by


adds an


further commit, which will drop bdrv_co_prwv together with is_write
logic, to keep read and write path separate.


keep the



Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Eric Blake 


R-b stands.

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




[PATCH 1/6] spapr: add spapr_machine_using_legacy_numa() helper

2020-09-23 Thread Daniel Henrique Barboza
The changes to come to NUMA support are all guest visible. In
theory we could just create a new 5_1 class option flag to
avoid the changes to cascade to 5.1 and under. The reality is that
these changes are only relevant if the machine has more than one
NUMA node. There is no need to change guest behavior that has
been around for years needlesly.

This new helper will be used by the next patches to determine
whether we should retain the (soon to be) legacy NUMA behavior
in the pSeries machine. The new behavior will only be exposed
if:

- machine is pseries-5.2 and newer;
- more than one NUMA node is declared in NUMA state.

Reviewed-by: David Gibson 
Signed-off-by: Daniel Henrique Barboza 
---
 hw/ppc/spapr.c | 12 
 include/hw/ppc/spapr.h |  2 ++
 2 files changed, 14 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index e813c7cfb9..c5d8910a74 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -294,6 +294,15 @@ static hwaddr spapr_node0_size(MachineState *machine)
 return machine->ram_size;
 }
 
+bool spapr_machine_using_legacy_numa(SpaprMachineState *spapr)
+{
+MachineState *machine = MACHINE(spapr);
+SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
+
+return smc->pre_5_2_numa_associativity ||
+   machine->numa_state->num_nodes <= 1;
+}
+
 static void add_str(GString *s, const gchar *s1)
 {
 g_string_append_len(s, s1, strlen(s1) + 1);
@@ -4522,8 +4531,11 @@ DEFINE_SPAPR_MACHINE(5_2, "5.2", true);
  */
 static void spapr_machine_5_1_class_options(MachineClass *mc)
 {
+SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
 spapr_machine_5_2_class_options(mc);
 compat_props_add(mc->compat_props, hw_compat_5_1, hw_compat_5_1_len);
+smc->pre_5_2_numa_associativity = true;
 }
 
 DEFINE_SPAPR_MACHINE(5_1, "5.1", false);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 114e819969..d1aae03b97 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -143,6 +143,7 @@ struct SpaprMachineClass {
 bool smp_threads_vsmt; /* set VSMT to smp_threads by default */
 hwaddr rma_limit;  /* clamp the RMA to this size */
 bool pre_5_1_assoc_refpoints;
+bool pre_5_2_numa_associativity;
 
 void (*phb_placement)(SpaprMachineState *spapr, uint32_t index,
   uint64_t *buid, hwaddr *pio, 
@@ -860,6 +861,7 @@ int spapr_max_server_number(SpaprMachineState *spapr);
 void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex,
   uint64_t pte0, uint64_t pte1);
 void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered);
+bool spapr_machine_using_legacy_numa(SpaprMachineState *spapr);
 
 /* DRC callbacks. */
 void spapr_core_release(DeviceState *dev);
-- 
2.26.2




Re: [PATCH v2 14/38] qapi/common.py: Convert comments into docstrings, and elaborate

2020-09-23 Thread Cleber Rosa
On Tue, Sep 22, 2020 at 05:00:37PM -0400, John Snow wrote:
> As docstrings, they'll show up in documentation and IDE help.
> 
> Signed-off-by: John Snow 
> ---
>  scripts/qapi/common.py | 51 ++
>  1 file changed, 37 insertions(+), 14 deletions(-)
> 
> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
> index 0ce4a107e6..730283722a 100644
> --- a/scripts/qapi/common.py
> +++ b/scripts/qapi/common.py
> @@ -20,10 +20,18 @@
>  _C_NAME_TRANS = str.maketrans('.-', '__')
>  
>  
> -# ENUMName -> ENUM_NAME, EnumName1 -> ENUM_NAME1
> -# ENUM_NAME -> ENUM_NAME, ENUM_NAME1 -> ENUM_NAME1, ENUM_Name2 -> ENUM_NAME2
> -# ENUM24_Name -> ENUM24_NAME
>  def camel_to_upper(value: str) -> str:
> +"""
> +Converts CamelCase to CAMEL_CASE.
> +
> +Examples:
> +  ENUMName -> ENUM_NAME
> +  EnumName1 -> ENUM_NAME1
> +  ENUM_NAME -> ENUM_NAME
> +  ENUM_NAME1 -> ENUM_NAME1
> +  ENUM_Name2 -> ENUM_NAME2
> +  ENUM24_Name -> ENUM24_NAME
> +"""
>  c_fun_str = c_name(value, False)
>  if value.isupper():
>  return c_fun_str
> @@ -45,21 +53,33 @@ def camel_to_upper(value: str) -> str:
>  def c_enum_const(type_name: str,
>   const_name: str,
>   prefix: Optional[str] = None) -> str:
> +"""
> +Generate a C enumeration constant name.
> +
> +:param type_name: The name of the enumeration.
> +:param const_name: The name of this constant.
> +:param prefix: Optional, prefix that overrides the type_name.
> +"""
>  if prefix is not None:
>  type_name = prefix
>  return camel_to_upper(type_name) + '_' + c_name(const_name, 
> False).upper()
>  
>  
> -# Map @name to a valid C identifier.
> -# If @protect, avoid returning certain ticklish identifiers (like
> -# C keywords) by prepending 'q_'.
> -#
> -# Used for converting 'name' from a 'name':'type' qapi definition
> -# into a generated struct member, as well as converting type names
> -# into substrings of a generated C function name.
> -# '__a.b_c' -> '__a_b_c', 'x-foo' -> 'x_foo'
> -# protect=True: 'int' -> 'q_int'; protect=False: 'int' -> 'int'
>  def c_name(name: str, protect: bool = True) -> str:
> +"""
> +Map `name` to a valid C identifier.
> +
> +Used for converting 'name' from a 'name':'type' qapi definition
> +into a generated struct member, as well as converting type names
> +into substrings of a generated C function name.
> +
> +'__a.b_c' -> '__a_b_c', 'x-foo' -> 'x_foo'
> +protect=True: 'int' -> 'q_int'; protect=False: 'int' -> 'int'
> +
> +:param name: The name to map.
> +:param protect: If true, avoid returning certain ticklish identifiers
> +(like C keywords) by prepending ``q_``.
> +"""
>  # ANSI X3J11/88-090, 3.1.1
>  c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue',
>   'default', 'do', 'double', 'else', 'enum', 'extern',
> @@ -134,9 +154,12 @@ def decrease(self, amount: int = 4) -> int:
>  indent = Indentation()
>  
>  
> -# Generate @code with @kwds interpolated.
> -# Obey indent, and strip EATSPACE.
>  def cgen(code: str, **kwds: object) -> str:
> +"""
> +Generate `code` with `kwds` interpolated.
> +
> +Obey `indent`, and strip `EATSPACE`.
> +"""

This probably won't help on IDEs (never checked any), but sphinx will
let you do:

   """
   Generate `code` with `kwds` interpolated.

   Obey `indent`, and strip :data:`EATSPACE`.
   """

I'm not sure that a maximum level of docstring "sphinxzation" is the
goal here, though.

Reviewed-by: Cleber Rosa 


signature.asc
Description: PGP signature


[PATCH 3/6] spapr_numa: translate regular NUMA distance to PAPR distance

2020-09-23 Thread Daniel Henrique Barboza
QEMU allows the user to set NUMA distances in the command line.
For ACPI architectures like x86, this means that user input is
used to populate the SLIT table, and the guest perceives the
distances as the user chooses to.

PPC64 does not work that way. In the PAPR concept of NUMA,
associativity relations between the NUMA nodes are provided by
the device tree, and the guest kernel is free to calculate the
distances as it sees fit. Given how ACPI architectures works,
this puts the pSeries machine in a strange spot - users expect
to define NUMA distances like in the ACPI case, but QEMU does
not have control over it. To give pSeries users a similar
experience, we'll need to bring kernel specifics to QEMU
to approximate the NUMA distances.

The pSeries kernel works with the NUMA distance range 10,
20, 40, 80 and 160. The code starts at 10 (local distance) and
searches for a match in the first NUMA level between the
resources. If there is no match, the distance is doubled and
then it proceeds to try to match in the next NUMA level. Rinse
and repeat for MAX_DISTANCE_REF_POINTS levels.

This patch introduces a spapr_numa_PAPRify_distances() helper
that translates the user distances to kernel distance, which
we're going to use to determine the associativity domains for
the NUMA nodes.

Signed-off-by: Daniel Henrique Barboza 
---
 hw/ppc/spapr_numa.c | 44 
 1 file changed, 44 insertions(+)

diff --git a/hw/ppc/spapr_numa.c b/hw/ppc/spapr_numa.c
index 36aaa273ee..180800b2f3 100644
--- a/hw/ppc/spapr_numa.c
+++ b/hw/ppc/spapr_numa.c
@@ -37,6 +37,49 @@ static bool spapr_numa_is_symmetrical(MachineState *ms)
 return true;
 }
 
+/*
+ * This function will translate the user distances into
+ * what the kernel understand as possible values: 10
+ * (local distance), 20, 40, 80 and 160. Current heuristic
+ * is:
+ *
+ *  - distances between 11 and 30 -> rounded to 20
+ *  - distances between 31 and 60 -> rounded to 40
+ *  - distances between 61 and 120 -> rounded to 80
+ *  - everything above 120 -> 160
+ *
+ * This step can also be done in the same time as the NUMA
+ * associativity domains calculation, at the cost of extra
+ * complexity. We chose to keep it simpler.
+ *
+ * Note: this will overwrite the distance values in
+ * ms->numa_state->nodes.
+ */
+static void spapr_numa_PAPRify_distances(MachineState *ms)
+{
+int src, dst;
+int nb_numa_nodes = ms->numa_state->num_nodes;
+NodeInfo *numa_info = ms->numa_state->nodes;
+
+for (src = 0; src < nb_numa_nodes; src++) {
+for (dst = src; dst < nb_numa_nodes; dst++) {
+uint8_t distance = numa_info[src].distance[dst];
+uint8_t rounded_distance = 160;
+
+if (distance > 11 && distance < 30) {
+rounded_distance = 20;
+} else if (distance > 31 && distance < 60) {
+rounded_distance = 40;
+} else if (distance > 61 && distance < 120) {
+rounded_distance = 80;
+}
+
+numa_info[src].distance[dst] = rounded_distance;
+numa_info[dst].distance[src] = rounded_distance;
+}
+}
+}
+
 void spapr_numa_associativity_init(SpaprMachineState *spapr,
MachineState *machine)
 {
@@ -95,6 +138,7 @@ void spapr_numa_associativity_init(SpaprMachineState *spapr,
 exit(1);
 }
 
+spapr_numa_PAPRify_distances(machine);
 }
 
 void spapr_numa_write_associativity_dt(SpaprMachineState *spapr, void *fdt,
-- 
2.26.2




[PATCH 4/6] spapr_numa: change reference-points and maxdomain settings

2020-09-23 Thread Daniel Henrique Barboza
This is the first guest visible change introduced in
spapr_numa.c. The previous settings of both reference-points
and maxdomains were too restrictive, but enough for the
existing associativity we're setting in the resources.

We'll change that in the following patches, populating the
associativity arrays based on user input. For those changes
to be effective, reference-points and maxdomains must be
more flexible. After this patch, we'll have 4 distinct
levels of NUMA (0x4, 0x3, 0x2, 0x1) and maxdomains will
allow for any type of configuration the user intends to
do - under the scope and limitations of PAPR itself, of
course.

Signed-off-by: Daniel Henrique Barboza 
---
 hw/ppc/spapr_numa.c | 27 ++-
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/hw/ppc/spapr_numa.c b/hw/ppc/spapr_numa.c
index 180800b2f3..688391278e 100644
--- a/hw/ppc/spapr_numa.c
+++ b/hw/ppc/spapr_numa.c
@@ -222,21 +222,30 @@ int 
spapr_numa_write_assoc_lookup_arrays(SpaprMachineState *spapr, void *fdt,
  */
 void spapr_numa_write_rtas_dt(SpaprMachineState *spapr, void *fdt, int rtas)
 {
+MachineState *ms = MACHINE(spapr);
 SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
 uint32_t refpoints[] = {
 cpu_to_be32(0x4),
-cpu_to_be32(0x4),
+cpu_to_be32(0x3),
 cpu_to_be32(0x2),
+cpu_to_be32(0x1),
 };
 uint32_t nr_refpoints = ARRAY_SIZE(refpoints);
-uint32_t maxdomain = cpu_to_be32(spapr->gpu_numa_id > 1 ? 1 : 0);
-uint32_t maxdomains[] = {
-cpu_to_be32(4),
-maxdomain,
-maxdomain,
-maxdomain,
-cpu_to_be32(spapr->gpu_numa_id),
-};
+uint32_t maxdomain = cpu_to_be32(ms->numa_state->num_nodes +
+ spapr->gpu_numa_id);
+uint32_t maxdomains[] = {0x4, maxdomain, maxdomain, maxdomain, maxdomain};
+
+if (spapr_machine_using_legacy_numa(spapr)) {
+refpoints[1] =  cpu_to_be32(0x4);
+refpoints[2] =  cpu_to_be32(0x2);
+nr_refpoints = 3;
+
+maxdomain = cpu_to_be32(spapr->gpu_numa_id > 1 ? 1 : 0);
+maxdomains[1] = maxdomain;
+maxdomains[2] = maxdomain;
+maxdomains[3] = maxdomain;
+maxdomains[4] = cpu_to_be32(spapr->gpu_numa_id);
+}
 
 if (smc->pre_5_1_assoc_refpoints) {
 nr_refpoints = 2;
-- 
2.26.2




[PATCH 0/6] pseries NUMA distance calculation

2020-09-23 Thread Daniel Henrique Barboza
Hi,

This series is a follow-up of the reworked pSeries NUMA
code that is already merged upstream. It contains some of
the patches that were presented in the first version of this
work [1], some of them changed based on the reviews made
back there. 

With this series, we're able to take user input into consideration
when setting up the NUMA topology of the guest. It is still an
approximation, but at least user input is not completely ignored.

The changes will only be effective with pseries-5.2 and newer
machines, and if more than one NUMA node is declared by the user.
The idea is that we don't want to tamper with legacy guest behavior.
Patch 6 has examples of how we are approximating NUMA distance
via user input.

The series was rebased using David's ppc-for-5.2 at
4cca31df828.


Changes carried over from [1]:
- patch 1 (former 4): same patch, added David's r-b
- patch 2 (former 2): the check for asymetrical NUMA was moved
to spapr code as requested in the review
- patch 4 is a merge of former patches 5 and 6
- patch 5 (former 9): reworked
- patch 6 (former 10): same patch

Patch 3 is new in the series.



[1] https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg03169.html



Daniel Henrique Barboza (6):
  spapr: add spapr_machine_using_legacy_numa() helper
  spapr_numa: forbid asymmetrical NUMA setups
  spapr_numa: translate regular NUMA distance to PAPR distance
  spapr_numa: change reference-points and maxdomain settings
  spapr_numa: consider user input when defining associativity
  specs/ppc-spapr-numa: update with new NUMA support

 docs/specs/ppc-spapr-numa.rst | 213 ++
 hw/ppc/spapr.c|  12 ++
 hw/ppc/spapr_numa.c   | 184 +++--
 include/hw/ppc/spapr.h|   2 +
 4 files changed, 402 insertions(+), 9 deletions(-)

-- 
2.26.2




[PATCH 6/6] specs/ppc-spapr-numa: update with new NUMA support

2020-09-23 Thread Daniel Henrique Barboza
This update provides more in depth information about the
choices and drawbacks of the new NUMA support for the
spapr machine.

Signed-off-by: Daniel Henrique Barboza 
---
 docs/specs/ppc-spapr-numa.rst | 213 ++
 1 file changed, 213 insertions(+)

diff --git a/docs/specs/ppc-spapr-numa.rst b/docs/specs/ppc-spapr-numa.rst
index e762038022..994bfb996f 100644
--- a/docs/specs/ppc-spapr-numa.rst
+++ b/docs/specs/ppc-spapr-numa.rst
@@ -189,3 +189,216 @@ QEMU up to 5.1, as follows:
 
 This also means that user input in QEMU command line does not change the
 NUMA distancing inside the guest for the pseries machine.
+
+New NUMA mechanics for pseries in QEMU 5.2
+==
+
+Starting in QEMU 5.2, the pseries machine now considers user input when
+setting NUMA topology of the guest. The following changes were made:
+
+* ibm,associativity-reference-points was changed to {0x4, 0x3, 0x2, 0x1}, 
allowing
+  for 4 distinct NUMA distance values based on the NUMA levels
+
+* ibm,max-associativity-domains was changed to support multiple associativity
+  domains in all NUMA levels. This is needed to ensure user flexibility
+
+* ibm,associativity for all resources now varies with user input
+
+These changes are only effective for pseries-5.2 and newer machines that are
+created with more than one NUMA node (disconsidering NUMA nodes created by
+the machine itself, e.g. NVLink 2 GPUs). The now legacy support has been
+around for such a long time, with users seeing NUMA distances 10 and 40
+(and 80 if using NVLink2 GPUs), and there is no need to disrupt the
+existing experience of those guests.
+
+To bring the user experience x86 users have when tuning up NUMA, we had
+to operate under the current pseries Linux kernel logic described in
+`How the pseries Linux guest calculates NUMA distances`_. The result
+is that we needed to translate NUMA distance user input to pseries
+Linux kernel input.
+
+Translating user distance to kernel distance
+
+
+User input for NUMA distance can vary from 10 to 254. We need to translate
+that to the values that the Linux kernel operates on (10, 20, 40, 80, 160).
+This is how it is being done:
+
+* user distance 11 to 30 will be interpreted as 20
+* user distance 31 to 60 will be interpreted as 40
+* user distance 61 to 120 will be interpreted as 80
+* user distance 121 and beyond will be interpreted as 160
+* user distance 10 stays 10
+
+The reasoning behind this aproximation is to avoid any round up to the local
+distance (10), keeping it exclusive to the 4th NUMA level (which is still
+exclusive to the node_id). All other ranges were chosen under the developer
+discretion of what would be (somewhat) sensible considering the user input.
+Any other strategy can be used here, but in the end the reality is that we'll
+have to accept that a large array of values will be translated to the same
+NUMA topology in the guest, e.g. this user input:
+
+::
+
+  0   1   2
+  0  10  31 120
+  1  31  10  30
+  2 120  30  10
+
+And this other user input:
+
+::
+
+  0   1   2
+  0  10  60  61
+  1  60  10  11
+  2  61  11  10
+
+Will both be translated to the same values internally:
+
+::
+
+  0   1   2
+  0  10  40  80
+  1  40  10  20
+  2  80  20  10
+
+Users are encouraged to use only the kernel values in the NUMA definition to
+avoid being taken by surprise with that the guest is actually seeing in the
+topology. There are enough potential surprises that are inherent to the
+associativity domain assignment process, discussed below.
+
+
+How associativity domains are assigned
+--
+
+LOPAPR allows more than one associativity array (or 'string') per allocated
+resource. This would be used to represent that the resource has multiple
+connections with the board, and then the operational system, when deciding
+NUMA distancing, should consider the associativity information that provides
+the shortest distance.
+
+The spapr implementation does not support multiple associativity arrays per
+resource, neither does the pseries Linux kernel. We'll have to represent the
+NUMA topology using one associativity per resource, which means that choices
+and compromises are going to be made.
+
+Consider the following NUMA topology entered by user input:
+
+::
+
+  0   1   2   3
+  0  10  20  20  40
+  1  20  10  80  40
+  2  20  80  10  20
+  3  40  40  20  10
+
+Honoring just the relative distances of node 0 to every other node, one 
possible
+value for all associativity arrays would be:
+
+* node 0: 0 B A 0
+* node 1: 0 0 A 1
+* node 2: 0 0 A 2
+* node 3: 0 B 0 3
+
+With the reference points {0x4, 0x3, 0x2, 0x1}, for node 0:
+
+* distance from 0 to 1 is 20 (no match at 0x4, will match at 0x3)
+* distance from 0 to 2 is 20 (no match at 0x4, will match at 0x3)
+* distance from 0 to 3 is 40 (no match at 0x4 and 0x3, will match
+  at 0x2)
+
+The distances related to 

[PATCH 2/6] spapr_numa: forbid asymmetrical NUMA setups

2020-09-23 Thread Daniel Henrique Barboza
The pSeries machine does not support asymmetrical NUMA
configurations. This doesn't make much of a different
since we're not using user input for pSeries NUMA setup,
but this will change in the next patches.

To avoid breaking existing setups, gate this change by
checking for legacy NUMA support.

Signed-off-by: Daniel Henrique Barboza 
---
 hw/ppc/spapr_numa.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/hw/ppc/spapr_numa.c b/hw/ppc/spapr_numa.c
index 64fe567f5d..36aaa273ee 100644
--- a/hw/ppc/spapr_numa.c
+++ b/hw/ppc/spapr_numa.c
@@ -19,6 +19,24 @@
 /* Moved from hw/ppc/spapr_pci_nvlink2.c */
 #define SPAPR_GPU_NUMA_ID   (cpu_to_be32(1))
 
+static bool spapr_numa_is_symmetrical(MachineState *ms)
+{
+int src, dst;
+int nb_numa_nodes = ms->numa_state->num_nodes;
+NodeInfo *numa_info = ms->numa_state->nodes;
+
+for (src = 0; src < nb_numa_nodes; src++) {
+for (dst = src; dst < nb_numa_nodes; dst++) {
+if (numa_info[src].distance[dst] !=
+numa_info[dst].distance[src]) {
+return false;
+}
+}
+}
+
+return true;
+}
+
 void spapr_numa_associativity_init(SpaprMachineState *spapr,
MachineState *machine)
 {
@@ -61,6 +79,22 @@ void spapr_numa_associativity_init(SpaprMachineState *spapr,
 
 spapr->numa_assoc_array[i][MAX_DISTANCE_REF_POINTS] = cpu_to_be32(i);
 }
+
+/*
+ * Legacy NUMA guests (pseries-5.1 and order, or guests with only
+ * 1 NUMA node) will not benefit from anything we're going to do
+ * after this point.
+ */
+if (spapr_machine_using_legacy_numa(spapr)) {
+return;
+}
+
+if (!spapr_numa_is_symmetrical(machine)) {
+error_report("Asymmetrical NUMA topologies aren't supported "
+ "in the pSeries machine");
+exit(1);
+}
+
 }
 
 void spapr_numa_write_associativity_dt(SpaprMachineState *spapr, void *fdt,
-- 
2.26.2




Re: [PATCH v2 13/38] qapi/common.py: add type hint annotations

2020-09-23 Thread Cleber Rosa
On Tue, Sep 22, 2020 at 05:00:36PM -0400, John Snow wrote:
> Annotations do not change runtime behavior.
> This commit *only* adds annotations.
> 
> Signed-off-by: John Snow 

Reviewed-by: Cleber Rosa 


signature.asc
Description: PGP signature


Re: [PATCH 02/16] qapi/expr.py: Check for dict instead of OrderedDict

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:12:59PM -0400, John Snow wrote:
> OrderedDict is a subtype of dict, so we can check for a more general form.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH 01/16] qapi/expr.py: Remove 'info' argument from nested check_if_str

2020-09-23 Thread Eduardo Habkost
On Tue, Sep 22, 2020 at 05:12:58PM -0400, John Snow wrote:
> The function can just use the argument from the scope above. Otherwise,
> we get shadowed argument errors because the parameter name clashes with
> the name of a variable already in-scope.
> 
> Signed-off-by: John Snow 

Reviewed-by: Eduardo Habkost 

-- 
Eduardo




  1   2   3   4   5   >