|
@@ -946,7 +946,25 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ qatomic_store_release(&dev->realized, value);
|
|
|
|
+
|
|
} else if (!value && dev->realized) {
|
|
} else if (!value && dev->realized) {
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Change the value so that any concurrent users are aware
|
|
|
|
+ * that the device is going to be unrealized
|
|
|
|
+ *
|
|
|
|
+ * TODO: change .realized property to enum that states
|
|
|
|
+ * each phase of the device realization/unrealization
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ qatomic_set(&dev->realized, value);
|
|
|
|
+ /*
|
|
|
|
+ * Ensure that concurrent users see this update prior to
|
|
|
|
+ * any other changes done by unrealize.
|
|
|
|
+ */
|
|
|
|
+ smp_wmb();
|
|
|
|
+
|
|
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
|
|
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
|
|
qbus_unrealize(bus);
|
|
qbus_unrealize(bus);
|
|
}
|
|
}
|
|
@@ -961,7 +979,6 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
|
|
}
|
|
}
|
|
|
|
|
|
assert(local_err == NULL);
|
|
assert(local_err == NULL);
|
|
- dev->realized = value;
|
|
|
|
return;
|
|
return;
|
|
|
|
|
|
child_realize_fail:
|
|
child_realize_fail:
|