forked from Minki/linux
xen/xenbus: fix locking
Commit060eabe8fb
("xenbus/backend: Protect xenbus callback with lock") introduced a bug by holding a lock while calling a function which might schedule. Fix that by using a semaphore instead. Fixes:060eabe8fb
("xenbus/backend: Protect xenbus callback with lock") Signed-off-by: Juergen Gross <jgross@suse.com> Link: https://lore.kernel.org/r/20200305100323.16736-1-jgross@suse.com Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
This commit is contained in:
parent
8130b9d5b5
commit
2f69a110e7
@ -239,9 +239,9 @@ int xenbus_dev_probe(struct device *_dev)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
spin_lock(&dev->reclaim_lock);
|
||||
down(&dev->reclaim_sem);
|
||||
err = drv->probe(dev, id);
|
||||
spin_unlock(&dev->reclaim_lock);
|
||||
up(&dev->reclaim_sem);
|
||||
if (err)
|
||||
goto fail_put;
|
||||
|
||||
@ -271,9 +271,9 @@ int xenbus_dev_remove(struct device *_dev)
|
||||
free_otherend_watch(dev);
|
||||
|
||||
if (drv->remove) {
|
||||
spin_lock(&dev->reclaim_lock);
|
||||
down(&dev->reclaim_sem);
|
||||
drv->remove(dev);
|
||||
spin_unlock(&dev->reclaim_lock);
|
||||
up(&dev->reclaim_sem);
|
||||
}
|
||||
|
||||
module_put(drv->driver.owner);
|
||||
@ -473,7 +473,7 @@ int xenbus_probe_node(struct xen_bus_type *bus,
|
||||
goto fail;
|
||||
|
||||
dev_set_name(&xendev->dev, "%s", devname);
|
||||
spin_lock_init(&xendev->reclaim_lock);
|
||||
sema_init(&xendev->reclaim_sem, 1);
|
||||
|
||||
/* Register with generic device framework. */
|
||||
err = device_register(&xendev->dev);
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/semaphore.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
@ -257,10 +258,10 @@ static int backend_reclaim_memory(struct device *dev, void *data)
|
||||
drv = to_xenbus_driver(dev->driver);
|
||||
if (drv && drv->reclaim_memory) {
|
||||
xdev = to_xenbus_device(dev);
|
||||
if (!spin_trylock(&xdev->reclaim_lock))
|
||||
if (down_trylock(&xdev->reclaim_sem))
|
||||
return 0;
|
||||
drv->reclaim_memory(xdev);
|
||||
spin_unlock(&xdev->reclaim_lock);
|
||||
up(&xdev->reclaim_sem);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <linux/completion.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <xen/interface/xen.h>
|
||||
#include <xen/interface/grant_table.h>
|
||||
#include <xen/interface/io/xenbus.h>
|
||||
@ -76,7 +77,7 @@ struct xenbus_device {
|
||||
enum xenbus_state state;
|
||||
struct completion down;
|
||||
struct work_struct work;
|
||||
spinlock_t reclaim_lock;
|
||||
struct semaphore reclaim_sem;
|
||||
};
|
||||
|
||||
static inline struct xenbus_device *to_xenbus_device(struct device *dev)
|
||||
|
Loading…
Reference in New Issue
Block a user