# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID d2705953c6d268779a4612b0115dc52b34f4f68c
# Parent 8031bf331472d3150ac3ef934922a5cc05e22c84
More simplifications to blkback:
1. Remove blkif->status field as it's really not needed.
2. Simplify connection logic.
3. Get rid of atomic_t io_pending. There's no need for
atomic r-m-w updates to the work-to-do flag, so replace
with an integer and add barriers where serialisation is
required.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
diff -r 8031bf331472 -r d2705953c6d2
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Thu Apr 6
10:13:33 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Thu Apr 6
10:34:14 2006
@@ -225,16 +225,16 @@
while (!kthread_should_stop()) {
wait_event_interruptible(
blkif->wq,
- atomic_read(&blkif->io_pending) ||
- kthread_should_stop());
+ blkif->waiting_reqs || kthread_should_stop());
wait_event_interruptible(
pending_free_wq,
- !list_empty(&pending_free) ||
- kthread_should_stop());
-
- atomic_set(&blkif->io_pending, 0);
+ !list_empty(&pending_free) || kthread_should_stop());
+
+ blkif->waiting_reqs = 0;
+ smp_mb(); /* clear flag *before* checking for work */
+
if (do_block_io_op(blkif))
- atomic_inc(&blkif->io_pending);
+ blkif->waiting_reqs = 1;
unplug_queue(blkif);
if (log_stats && time_after(jiffies, blkif->st_print))
@@ -287,12 +287,15 @@
* NOTIFICATION FROM GUEST OS.
*/
+void blkif_notify_work(blkif_t *blkif)
+{
+ blkif->waiting_reqs = 1;
+ wake_up(&blkif->wq);
+}
+
irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs)
{
- blkif_t *blkif = dev_id;
-
- atomic_inc(&blkif->io_pending);
- wake_up(&blkif->wq);
+ blkif_notify_work(dev_id);
return IRQ_HANDLED;
}
@@ -512,10 +515,8 @@
}
spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
- if (more_to_do) {
- atomic_inc(&blkif->io_pending);
- wake_up(&blkif->wq);
- }
+ if (more_to_do)
+ blkif_notify_work(blkif);
if (notify)
notify_remote_via_irq(blkif->irq);
}
diff -r 8031bf331472 -r d2705953c6d2
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Apr 6 10:13:33 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Apr 6 10:34:14 2006
@@ -72,7 +72,6 @@
/* Back pointer to the backend_info. */
struct backend_info *be;
/* Private fields. */
- enum { DISCONNECTED, CONNECTED } status;
#ifdef CONFIG_XEN_BLKDEV_TAP_BE
/* Is this a blktap frontend */
unsigned int is_blktap;
@@ -82,7 +81,7 @@
wait_queue_head_t wq;
struct task_struct *xenblkd;
- atomic_t io_pending;
+ unsigned int waiting_reqs;
request_queue_t *plug;
/* statistics */
@@ -130,10 +129,9 @@
void blkif_xenbus_init(void);
+void blkif_notify_work(blkif_t *blkif);
irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
int blkif_schedule(void *arg);
-
-void update_blkif_status(blkif_t *blkif);
#endif /* __BLKIF__BACKEND__COMMON_H__ */
diff -r 8031bf331472 -r d2705953c6d2
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Thu Apr 6
10:13:33 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Thu Apr 6
10:34:14 2006
@@ -45,7 +45,6 @@
memset(blkif, 0, sizeof(*blkif));
blkif->domid = domid;
- blkif->status = DISCONNECTED;
spin_lock_init(&blkif->blk_ring_lock);
atomic_set(&blkif->refcnt, 1);
init_waitqueue_head(&blkif->wq);
@@ -138,9 +137,6 @@
blkif->irq = bind_evtchn_to_irqhandler(
blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
- /* We're potentially connected now */
- update_blkif_status(blkif);
-
return 0;
}
diff -r 8031bf331472 -r d2705953c6d2
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu Apr 6 10:13:33 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu Apr 6 10:34:14 2006
@@ -16,7 +16,6 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
#include <stdarg.h>
#include <linux/module.h>
@@ -25,36 +24,33 @@
#include "common.h"
#undef DPRINTK
-#define DPRINTK(fmt, args...) \
- pr_debug("blkback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__,
##args)
-
+#define DPRINTK(fmt, args...) \
+ pr_debug("blkback/xenbus (%s:%d) " fmt ".\n", \
+ __FUNCTION__, __LINE__, ##args)
struct backend_info
{
struct xenbus_device *dev;
blkif_t *blkif;
struct xenbus_watch backend_watch;
-
unsigned major;
unsigned minor;
char *mode;
};
-
-static void maybe_connect(struct backend_info *);
static void connect(struct backend_info *);
static int connect_ring(struct backend_info *);
static void backend_changed(struct xenbus_watch *, const char **,
unsigned int);
-void update_blkif_status(blkif_t *blkif)
+static void update_blkif_status(blkif_t *blkif)
{
- if(blkif->irq && blkif->vbd.bdev) {
- blkif->status = CONNECTED;
- (void)blkif_be_int(0, blkif, NULL);
- }
- maybe_connect(blkif->be);
+ if (blkif->irq && blkif->vbd.bdev &&
+ (blkif->be->dev->state != XenbusStateConnected)) {
+ connect(blkif->be);
+ blkif_notify_work(blkif);
+ }
}
@@ -91,7 +87,6 @@
be->backend_watch.node = NULL;
}
if (be->blkif) {
- be->blkif->status = DISCONNECTED;
if (be->blkif->xenblkd)
kthread_stop(be->blkif->xenblkd);
blkif_put(be->blkif);
@@ -185,8 +180,8 @@
return;
}
- if (be->major && be->minor &&
- (be->major != major || be->minor != minor)) {
+ if ((be->major || be->minor) &&
+ ((be->major != major) || (be->minor != minor))) {
printk(KERN_WARNING
"blkback: changing physical device (from %x:%x to "
"%x:%x) not supported.\n", be->major, be->minor,
@@ -290,14 +285,6 @@
/* ** Connection ** */
-static void maybe_connect(struct backend_info *be)
-{
- if ((be->major != 0 || be->minor != 0) &&
- be->blkif->status == CONNECTED)
- connect(be);
-}
-
-
/**
* Write the physical details regarding the block device to the store, and
* switch to Connected state.
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|