xen: branch for v5.5-rc3
-----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQRTLbB6QfY48x44uB6AXGG7T9hjvgUCXf4bWAAKCRCAXGG7T9hj vt/NAQDCjLEeeOxpFf+FVCi0zNdsHq1G0WXvvk7zkudID69LqAD+IyplzCbGJQQ0 ND9nW4hvcJkmMt9Sx1+KF4FRy03bVwg= =NMEn -----END PGP SIGNATURE----- Merge tag 'for-linus-5.5b-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip Pull xen fixes from Juergen Gross: "This contains two cleanup patches and a small series for supporting reloading the Xen block backend driver" * tag 'for-linus-5.5b-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen/grant-table: remove multiple BUG_ON on gnttab_interface xen-blkback: support dynamic unbind/bind xen/interface: re-define FRONT/BACK_RING_ATTACH() xenbus: limit when state is forced to closed xenbus: move xenbus_dev_shutdown() into frontend code... xen/blkfront: Adjust indentation in xlvbd_alloc_gendisk
This commit is contained in:
commit
62af608b4b
|
@ -190,6 +190,9 @@ static int xen_blkif_map(struct xen_blkif_ring *ring, grant_ref_t *gref,
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct xen_blkif *blkif = ring->blkif;
|
struct xen_blkif *blkif = ring->blkif;
|
||||||
|
const struct blkif_common_sring *sring_common;
|
||||||
|
RING_IDX rsp_prod, req_prod;
|
||||||
|
unsigned int size;
|
||||||
|
|
||||||
/* Already connected through? */
|
/* Already connected through? */
|
||||||
if (ring->irq)
|
if (ring->irq)
|
||||||
|
@ -200,46 +203,62 @@ static int xen_blkif_map(struct xen_blkif_ring *ring, grant_ref_t *gref,
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
sring_common = (struct blkif_common_sring *)ring->blk_ring;
|
||||||
|
rsp_prod = READ_ONCE(sring_common->rsp_prod);
|
||||||
|
req_prod = READ_ONCE(sring_common->req_prod);
|
||||||
|
|
||||||
switch (blkif->blk_protocol) {
|
switch (blkif->blk_protocol) {
|
||||||
case BLKIF_PROTOCOL_NATIVE:
|
case BLKIF_PROTOCOL_NATIVE:
|
||||||
{
|
{
|
||||||
struct blkif_sring *sring;
|
struct blkif_sring *sring_native =
|
||||||
sring = (struct blkif_sring *)ring->blk_ring;
|
(struct blkif_sring *)ring->blk_ring;
|
||||||
BACK_RING_INIT(&ring->blk_rings.native, sring,
|
|
||||||
XEN_PAGE_SIZE * nr_grefs);
|
BACK_RING_ATTACH(&ring->blk_rings.native, sring_native,
|
||||||
|
rsp_prod, XEN_PAGE_SIZE * nr_grefs);
|
||||||
|
size = __RING_SIZE(sring_native, XEN_PAGE_SIZE * nr_grefs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BLKIF_PROTOCOL_X86_32:
|
case BLKIF_PROTOCOL_X86_32:
|
||||||
{
|
{
|
||||||
struct blkif_x86_32_sring *sring_x86_32;
|
struct blkif_x86_32_sring *sring_x86_32 =
|
||||||
sring_x86_32 = (struct blkif_x86_32_sring *)ring->blk_ring;
|
(struct blkif_x86_32_sring *)ring->blk_ring;
|
||||||
BACK_RING_INIT(&ring->blk_rings.x86_32, sring_x86_32,
|
|
||||||
XEN_PAGE_SIZE * nr_grefs);
|
BACK_RING_ATTACH(&ring->blk_rings.x86_32, sring_x86_32,
|
||||||
|
rsp_prod, XEN_PAGE_SIZE * nr_grefs);
|
||||||
|
size = __RING_SIZE(sring_x86_32, XEN_PAGE_SIZE * nr_grefs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BLKIF_PROTOCOL_X86_64:
|
case BLKIF_PROTOCOL_X86_64:
|
||||||
{
|
{
|
||||||
struct blkif_x86_64_sring *sring_x86_64;
|
struct blkif_x86_64_sring *sring_x86_64 =
|
||||||
sring_x86_64 = (struct blkif_x86_64_sring *)ring->blk_ring;
|
(struct blkif_x86_64_sring *)ring->blk_ring;
|
||||||
BACK_RING_INIT(&ring->blk_rings.x86_64, sring_x86_64,
|
|
||||||
XEN_PAGE_SIZE * nr_grefs);
|
BACK_RING_ATTACH(&ring->blk_rings.x86_64, sring_x86_64,
|
||||||
|
rsp_prod, XEN_PAGE_SIZE * nr_grefs);
|
||||||
|
size = __RING_SIZE(sring_x86_64, XEN_PAGE_SIZE * nr_grefs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = -EIO;
|
||||||
|
if (req_prod - rsp_prod > size)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
err = bind_interdomain_evtchn_to_irqhandler(blkif->domid, evtchn,
|
err = bind_interdomain_evtchn_to_irqhandler(blkif->domid, evtchn,
|
||||||
xen_blkif_be_int, 0,
|
xen_blkif_be_int, 0,
|
||||||
"blkif-backend", ring);
|
"blkif-backend", ring);
|
||||||
if (err < 0) {
|
if (err < 0)
|
||||||
xenbus_unmap_ring_vfree(blkif->be->dev, ring->blk_ring);
|
goto fail;
|
||||||
ring->blk_rings.common.sring = NULL;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
ring->irq = err;
|
ring->irq = err;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
xenbus_unmap_ring_vfree(blkif->be->dev, ring->blk_ring);
|
||||||
|
ring->blk_rings.common.sring = NULL;
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xen_blkif_disconnect(struct xen_blkif *blkif)
|
static int xen_blkif_disconnect(struct xen_blkif *blkif)
|
||||||
|
@ -1131,7 +1150,8 @@ static struct xenbus_driver xen_blkbk_driver = {
|
||||||
.ids = xen_blkbk_ids,
|
.ids = xen_blkbk_ids,
|
||||||
.probe = xen_blkbk_probe,
|
.probe = xen_blkbk_probe,
|
||||||
.remove = xen_blkbk_remove,
|
.remove = xen_blkbk_remove,
|
||||||
.otherend_changed = frontend_changed
|
.otherend_changed = frontend_changed,
|
||||||
|
.allow_rebind = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
int xen_blkif_xenbus_init(void)
|
int xen_blkif_xenbus_init(void)
|
||||||
|
|
|
@ -1113,8 +1113,8 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
|
||||||
if (!VDEV_IS_EXTENDED(info->vdevice)) {
|
if (!VDEV_IS_EXTENDED(info->vdevice)) {
|
||||||
err = xen_translate_vdev(info->vdevice, &minor, &offset);
|
err = xen_translate_vdev(info->vdevice, &minor, &offset);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
nr_parts = PARTS_PER_DISK;
|
nr_parts = PARTS_PER_DISK;
|
||||||
} else {
|
} else {
|
||||||
minor = BLKIF_MINOR_EXT(info->vdevice);
|
minor = BLKIF_MINOR_EXT(info->vdevice);
|
||||||
nr_parts = PARTS_PER_EXT_DISK;
|
nr_parts = PARTS_PER_EXT_DISK;
|
||||||
|
|
|
@ -664,7 +664,6 @@ static int grow_gnttab_list(unsigned int more_frames)
|
||||||
unsigned int nr_glist_frames, new_nr_glist_frames;
|
unsigned int nr_glist_frames, new_nr_glist_frames;
|
||||||
unsigned int grefs_per_frame;
|
unsigned int grefs_per_frame;
|
||||||
|
|
||||||
BUG_ON(gnttab_interface == NULL);
|
|
||||||
grefs_per_frame = gnttab_interface->grefs_per_grant_frame;
|
grefs_per_frame = gnttab_interface->grefs_per_grant_frame;
|
||||||
|
|
||||||
new_nr_grant_frames = nr_grant_frames + more_frames;
|
new_nr_grant_frames = nr_grant_frames + more_frames;
|
||||||
|
@ -1160,7 +1159,6 @@ EXPORT_SYMBOL_GPL(gnttab_unmap_refs_sync);
|
||||||
|
|
||||||
static unsigned int nr_status_frames(unsigned int nr_grant_frames)
|
static unsigned int nr_status_frames(unsigned int nr_grant_frames)
|
||||||
{
|
{
|
||||||
BUG_ON(gnttab_interface == NULL);
|
|
||||||
return gnttab_frames(nr_grant_frames, SPP);
|
return gnttab_frames(nr_grant_frames, SPP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1388,7 +1386,6 @@ static int gnttab_expand(unsigned int req_entries)
|
||||||
int rc;
|
int rc;
|
||||||
unsigned int cur, extra;
|
unsigned int cur, extra;
|
||||||
|
|
||||||
BUG_ON(gnttab_interface == NULL);
|
|
||||||
cur = nr_grant_frames;
|
cur = nr_grant_frames;
|
||||||
extra = ((req_entries + gnttab_interface->grefs_per_grant_frame - 1) /
|
extra = ((req_entries + gnttab_interface->grefs_per_grant_frame - 1) /
|
||||||
gnttab_interface->grefs_per_grant_frame);
|
gnttab_interface->grefs_per_grant_frame);
|
||||||
|
@ -1423,7 +1420,6 @@ int gnttab_init(void)
|
||||||
/* Determine the maximum number of frames required for the
|
/* Determine the maximum number of frames required for the
|
||||||
* grant reference free list on the current hypervisor.
|
* grant reference free list on the current hypervisor.
|
||||||
*/
|
*/
|
||||||
BUG_ON(gnttab_interface == NULL);
|
|
||||||
max_nr_glist_frames = (max_nr_grant_frames *
|
max_nr_glist_frames = (max_nr_grant_frames *
|
||||||
gnttab_interface->grefs_per_grant_frame / RPP);
|
gnttab_interface->grefs_per_grant_frame / RPP);
|
||||||
|
|
||||||
|
|
|
@ -116,8 +116,6 @@ int xenbus_probe_devices(struct xen_bus_type *bus);
|
||||||
|
|
||||||
void xenbus_dev_changed(const char *node, struct xen_bus_type *bus);
|
void xenbus_dev_changed(const char *node, struct xen_bus_type *bus);
|
||||||
|
|
||||||
void xenbus_dev_shutdown(struct device *_dev);
|
|
||||||
|
|
||||||
int xenbus_dev_suspend(struct device *dev);
|
int xenbus_dev_suspend(struct device *dev);
|
||||||
int xenbus_dev_resume(struct device *dev);
|
int xenbus_dev_resume(struct device *dev);
|
||||||
int xenbus_dev_cancel(struct device *dev);
|
int xenbus_dev_cancel(struct device *dev);
|
||||||
|
|
|
@ -255,7 +255,6 @@ fail_put:
|
||||||
module_put(drv->driver.owner);
|
module_put(drv->driver.owner);
|
||||||
fail:
|
fail:
|
||||||
xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
|
xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
|
||||||
xenbus_switch_state(dev, XenbusStateClosed);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xenbus_dev_probe);
|
EXPORT_SYMBOL_GPL(xenbus_dev_probe);
|
||||||
|
@ -276,34 +275,20 @@ int xenbus_dev_remove(struct device *_dev)
|
||||||
|
|
||||||
free_otherend_details(dev);
|
free_otherend_details(dev);
|
||||||
|
|
||||||
xenbus_switch_state(dev, XenbusStateClosed);
|
/*
|
||||||
|
* If the toolstack has forced the device state to closing then set
|
||||||
|
* the state to closed now to allow it to be cleaned up.
|
||||||
|
* Similarly, if the driver does not support re-bind, set the
|
||||||
|
* closed.
|
||||||
|
*/
|
||||||
|
if (!drv->allow_rebind ||
|
||||||
|
xenbus_read_driver_state(dev->nodename) == XenbusStateClosing)
|
||||||
|
xenbus_switch_state(dev, XenbusStateClosed);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xenbus_dev_remove);
|
EXPORT_SYMBOL_GPL(xenbus_dev_remove);
|
||||||
|
|
||||||
void xenbus_dev_shutdown(struct device *_dev)
|
|
||||||
{
|
|
||||||
struct xenbus_device *dev = to_xenbus_device(_dev);
|
|
||||||
unsigned long timeout = 5*HZ;
|
|
||||||
|
|
||||||
DPRINTK("%s", dev->nodename);
|
|
||||||
|
|
||||||
get_device(&dev->dev);
|
|
||||||
if (dev->state != XenbusStateConnected) {
|
|
||||||
pr_info("%s: %s: %s != Connected, skipping\n",
|
|
||||||
__func__, dev->nodename, xenbus_strstate(dev->state));
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
xenbus_switch_state(dev, XenbusStateClosing);
|
|
||||||
timeout = wait_for_completion_timeout(&dev->down, timeout);
|
|
||||||
if (!timeout)
|
|
||||||
pr_info("%s: %s timeout closing device\n",
|
|
||||||
__func__, dev->nodename);
|
|
||||||
out:
|
|
||||||
put_device(&dev->dev);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xenbus_dev_shutdown);
|
|
||||||
|
|
||||||
int xenbus_register_driver_common(struct xenbus_driver *drv,
|
int xenbus_register_driver_common(struct xenbus_driver *drv,
|
||||||
struct xen_bus_type *bus,
|
struct xen_bus_type *bus,
|
||||||
struct module *owner, const char *mod_name)
|
struct module *owner, const char *mod_name)
|
||||||
|
|
|
@ -198,7 +198,6 @@ static struct xen_bus_type xenbus_backend = {
|
||||||
.uevent = xenbus_uevent_backend,
|
.uevent = xenbus_uevent_backend,
|
||||||
.probe = xenbus_dev_probe,
|
.probe = xenbus_dev_probe,
|
||||||
.remove = xenbus_dev_remove,
|
.remove = xenbus_dev_remove,
|
||||||
.shutdown = xenbus_dev_shutdown,
|
|
||||||
.dev_groups = xenbus_dev_groups,
|
.dev_groups = xenbus_dev_groups,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -126,6 +126,28 @@ static int xenbus_frontend_dev_probe(struct device *dev)
|
||||||
return xenbus_dev_probe(dev);
|
return xenbus_dev_probe(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void xenbus_frontend_dev_shutdown(struct device *_dev)
|
||||||
|
{
|
||||||
|
struct xenbus_device *dev = to_xenbus_device(_dev);
|
||||||
|
unsigned long timeout = 5*HZ;
|
||||||
|
|
||||||
|
DPRINTK("%s", dev->nodename);
|
||||||
|
|
||||||
|
get_device(&dev->dev);
|
||||||
|
if (dev->state != XenbusStateConnected) {
|
||||||
|
pr_info("%s: %s: %s != Connected, skipping\n",
|
||||||
|
__func__, dev->nodename, xenbus_strstate(dev->state));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
xenbus_switch_state(dev, XenbusStateClosing);
|
||||||
|
timeout = wait_for_completion_timeout(&dev->down, timeout);
|
||||||
|
if (!timeout)
|
||||||
|
pr_info("%s: %s timeout closing device\n",
|
||||||
|
__func__, dev->nodename);
|
||||||
|
out:
|
||||||
|
put_device(&dev->dev);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct dev_pm_ops xenbus_pm_ops = {
|
static const struct dev_pm_ops xenbus_pm_ops = {
|
||||||
.suspend = xenbus_dev_suspend,
|
.suspend = xenbus_dev_suspend,
|
||||||
.resume = xenbus_frontend_dev_resume,
|
.resume = xenbus_frontend_dev_resume,
|
||||||
|
@ -146,7 +168,7 @@ static struct xen_bus_type xenbus_frontend = {
|
||||||
.uevent = xenbus_uevent_frontend,
|
.uevent = xenbus_uevent_frontend,
|
||||||
.probe = xenbus_frontend_dev_probe,
|
.probe = xenbus_frontend_dev_probe,
|
||||||
.remove = xenbus_dev_remove,
|
.remove = xenbus_dev_remove,
|
||||||
.shutdown = xenbus_dev_shutdown,
|
.shutdown = xenbus_frontend_dev_shutdown,
|
||||||
.dev_groups = xenbus_dev_groups,
|
.dev_groups = xenbus_dev_groups,
|
||||||
|
|
||||||
.pm = &xenbus_pm_ops,
|
.pm = &xenbus_pm_ops,
|
||||||
|
|
|
@ -125,34 +125,23 @@ struct __name##_back_ring { \
|
||||||
memset((_s)->pad, 0, sizeof((_s)->pad)); \
|
memset((_s)->pad, 0, sizeof((_s)->pad)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define FRONT_RING_INIT(_r, _s, __size) do { \
|
#define FRONT_RING_ATTACH(_r, _s, _i, __size) do { \
|
||||||
(_r)->req_prod_pvt = 0; \
|
(_r)->req_prod_pvt = (_i); \
|
||||||
(_r)->rsp_cons = 0; \
|
(_r)->rsp_cons = (_i); \
|
||||||
(_r)->nr_ents = __RING_SIZE(_s, __size); \
|
(_r)->nr_ents = __RING_SIZE(_s, __size); \
|
||||||
(_r)->sring = (_s); \
|
(_r)->sring = (_s); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define BACK_RING_INIT(_r, _s, __size) do { \
|
#define FRONT_RING_INIT(_r, _s, __size) FRONT_RING_ATTACH(_r, _s, 0, __size)
|
||||||
(_r)->rsp_prod_pvt = 0; \
|
|
||||||
(_r)->req_cons = 0; \
|
#define BACK_RING_ATTACH(_r, _s, _i, __size) do { \
|
||||||
|
(_r)->rsp_prod_pvt = (_i); \
|
||||||
|
(_r)->req_cons = (_i); \
|
||||||
(_r)->nr_ents = __RING_SIZE(_s, __size); \
|
(_r)->nr_ents = __RING_SIZE(_s, __size); \
|
||||||
(_r)->sring = (_s); \
|
(_r)->sring = (_s); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Initialize to existing shared indexes -- for recovery */
|
#define BACK_RING_INIT(_r, _s, __size) BACK_RING_ATTACH(_r, _s, 0, __size)
|
||||||
#define FRONT_RING_ATTACH(_r, _s, __size) do { \
|
|
||||||
(_r)->sring = (_s); \
|
|
||||||
(_r)->req_prod_pvt = (_s)->req_prod; \
|
|
||||||
(_r)->rsp_cons = (_s)->rsp_prod; \
|
|
||||||
(_r)->nr_ents = __RING_SIZE(_s, __size); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define BACK_RING_ATTACH(_r, _s, __size) do { \
|
|
||||||
(_r)->sring = (_s); \
|
|
||||||
(_r)->rsp_prod_pvt = (_s)->rsp_prod; \
|
|
||||||
(_r)->req_cons = (_s)->req_prod; \
|
|
||||||
(_r)->nr_ents = __RING_SIZE(_s, __size); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* How big is this ring? */
|
/* How big is this ring? */
|
||||||
#define RING_SIZE(_r) \
|
#define RING_SIZE(_r) \
|
||||||
|
|
|
@ -93,6 +93,7 @@ struct xenbus_device_id
|
||||||
struct xenbus_driver {
|
struct xenbus_driver {
|
||||||
const char *name; /* defaults to ids[0].devicetype */
|
const char *name; /* defaults to ids[0].devicetype */
|
||||||
const struct xenbus_device_id *ids;
|
const struct xenbus_device_id *ids;
|
||||||
|
bool allow_rebind; /* avoid setting xenstore closed during remove */
|
||||||
int (*probe)(struct xenbus_device *dev,
|
int (*probe)(struct xenbus_device *dev,
|
||||||
const struct xenbus_device_id *id);
|
const struct xenbus_device_id *id);
|
||||||
void (*otherend_changed)(struct xenbus_device *dev,
|
void (*otherend_changed)(struct xenbus_device *dev,
|
||||||
|
|
Loading…
Reference in New Issue