Commit 62af608b authored by Linus Torvalds's avatar Linus Torvalds

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
parents 6d04182d d6bd6cf9
...@@ -190,6 +190,9 @@ static int xen_blkif_map(struct xen_blkif_ring *ring, grant_ref_t *gref, ...@@ -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, ...@@ -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 = { ...@@ -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, ...@@ -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) ...@@ -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); ...@@ -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) ...@@ -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) ...@@ -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); ...@@ -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 @@ int xenbus_dev_probe(struct device *_dev) ...@@ -255,7 +255,6 @@ int xenbus_dev_probe(struct device *_dev)
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) ...@@ -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 = { ...@@ -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) ...@@ -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 = { ...@@ -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,35 +125,24 @@ struct __name##_back_ring { \ ...@@ -125,35 +125,24 @@ 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; \
(_r)->nr_ents = __RING_SIZE(_s, __size); \
(_r)->sring = (_s); \
} while (0)
/* Initialize to existing shared indexes -- for recovery */ #define BACK_RING_ATTACH(_r, _s, _i, __size) do { \
#define FRONT_RING_ATTACH(_r, _s, __size) do { \ (_r)->rsp_prod_pvt = (_i); \
(_r)->sring = (_s); \ (_r)->req_cons = (_i); \
(_r)->req_prod_pvt = (_s)->req_prod; \
(_r)->rsp_cons = (_s)->rsp_prod; \
(_r)->nr_ents = __RING_SIZE(_s, __size); \ (_r)->nr_ents = __RING_SIZE(_s, __size); \
} while (0)
#define BACK_RING_ATTACH(_r, _s, __size) do { \
(_r)->sring = (_s); \ (_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) } while (0)
#define BACK_RING_INIT(_r, _s, __size) BACK_RING_ATTACH(_r, _s, 0, __size)
/* How big is this ring? */ /* How big is this ring? */
#define RING_SIZE(_r) \ #define RING_SIZE(_r) \
((_r)->nr_ents) ((_r)->nr_ents)
......
...@@ -93,6 +93,7 @@ struct xenbus_device_id ...@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment