diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2011-07-22 01:09:49 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2011-07-22 01:09:49 -0400 |
commit | 3c3ed482dc077a67903a58c9e1aedba1bb18c18a (patch) | |
tree | ad3987515d68fcfa7155574e53ab47aabd41e593 /Documentation | |
parent | 6d7a5d1ea34495ecb1d608f0e40afba7776ee408 (diff) |
lguest: Simplify device initialization.
We used to notify the Host every time we updated a device's status. However,
it only really needs to know when we're resetting the device, or failed to
initialize it, or when we've finished our feature negotiation.
In particular, we used to wait for VIRTIO_CONFIG_S_DRIVER_OK in the
status byte before starting the device service threads. But this
corresponds to the successful finish of device initialization, which
might (like virtio_blk's partition scanning) use the device. So we
had a hack, if they used the device before we expected we started the
threads anyway.
Now we hook into the finalize_features hook in the Guest: at that
point we tell the Launcher that it can rely on the features we have
acked. On the Launcher side, we look at the status at that point, and
start servicing the device.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/virtual/lguest/lguest.c | 25 |
1 files changed, 6 insertions, 19 deletions
diff --git a/Documentation/virtual/lguest/lguest.c b/Documentation/virtual/lguest/lguest.c index e3b9bb7a644a..80261d34da3d 100644 --- a/Documentation/virtual/lguest/lguest.c +++ b/Documentation/virtual/lguest/lguest.c | |||
@@ -1095,9 +1095,10 @@ static void update_device_status(struct device *dev) | |||
1095 | warnx("Device %s configuration FAILED", dev->name); | 1095 | warnx("Device %s configuration FAILED", dev->name); |
1096 | if (dev->running) | 1096 | if (dev->running) |
1097 | reset_device(dev); | 1097 | reset_device(dev); |
1098 | } else if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK) { | 1098 | } else { |
1099 | if (!dev->running) | 1099 | if (dev->running) |
1100 | start_device(dev); | 1100 | err(1, "Device %s features finalized twice", dev->name); |
1101 | start_device(dev); | ||
1101 | } | 1102 | } |
1102 | } | 1103 | } |
1103 | 1104 | ||
@@ -1122,25 +1123,11 @@ static void handle_output(unsigned long addr) | |||
1122 | return; | 1123 | return; |
1123 | } | 1124 | } |
1124 | 1125 | ||
1125 | /* | 1126 | /* Devices should not be used before features are finalized. */ |
1126 | * Devices *can* be used before status is set to DRIVER_OK. | ||
1127 | * The original plan was that they would never do this: they | ||
1128 | * would always finish setting up their status bits before | ||
1129 | * actually touching the virtqueues. In practice, we allowed | ||
1130 | * them to, and they do (eg. the disk probes for partition | ||
1131 | * tables as part of initialization). | ||
1132 | * | ||
1133 | * If we see this, we start the device: once it's running, we | ||
1134 | * expect the device to catch all the notifications. | ||
1135 | */ | ||
1136 | for (vq = i->vq; vq; vq = vq->next) { | 1127 | for (vq = i->vq; vq; vq = vq->next) { |
1137 | if (addr != vq->config.pfn*getpagesize()) | 1128 | if (addr != vq->config.pfn*getpagesize()) |
1138 | continue; | 1129 | continue; |
1139 | if (i->running) | 1130 | errx(1, "Notification on %s before setup!", i->name); |
1140 | errx(1, "Notification on running %s", i->name); | ||
1141 | /* This just calls create_thread() for each virtqueue */ | ||
1142 | start_device(i); | ||
1143 | return; | ||
1144 | } | 1131 | } |
1145 | } | 1132 | } |
1146 | 1133 | ||