fw_cfg: amend callback behavior spec to once per select
commit3bef7e8aab8af2f86c5785761c37e068428c689d
authorGabriel L. Somlo <somlo@cmu.edu>
Thu, 5 Nov 2015 14:32:48 +0000 (5 09:32 -0500)
committerGerd Hoffmann <kraxel@redhat.com>
Tue, 15 Dec 2015 10:45:59 +0000 (15 11:45 +0100)
tree0bb7dadd51c237b9651c891ce85b605a51f746e5
parent9c4a5c55f5c6c63c24c29e5a3b57ddbc1e550303
fw_cfg: amend callback behavior spec to once per select

Currently, the fw_cfg internal API specifies that if an item was set up
with a read callback, the callback must be run each time a byte is read
from the item. This behavior is both wasteful (most items do not have a
read callback set), and impractical for bulk transfers (e.g., DMA read).

At the time of this writing, the only items configured with a callback
are "/etc/table-loader", "/etc/acpi/tables", and "/etc/acpi/rsdp". They
all share the same callback functions: virt_acpi_build_update() on ARM
(in hw/arm/virt-acpi-build.c), and acpi_build_update() on i386 (in
hw/i386/acpi.c). Both of these callbacks are one-shot (i.e. they return
without doing anything at all after the first time they are invoked with
a given build_state; since build_state is also shared across all three
items mentioned above, the callback only ever runs *once*, the first
time either of the listed items is read).

This patch amends the specification for fw_cfg_add_file_callback() to
state that any available read callback will only be invoked once each
time the item is selected. This change has no practical effect on the
current behavior of QEMU, and it enables us to significantly optimize
the behavior of fw_cfg reads during guest firmware setup, eliminating
a large amount of redundant callback checks and invocations.

Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Marc MarĂ­ <markmb@redhat.com>
Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-id: 1446733972-1602-3-git-send-email-somlo@cmu.edu
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
hw/nvram/fw_cfg.c
include/hw/nvram/fw_cfg.h