dm - get rid of excessive locking and redundancy
authorAlex Hornung <ahornung@gmail.com>
Thu, 14 Jul 2011 18:43:15 +0000 (19:43 +0100)
committerAlex Hornung <ahornung@gmail.com>
Sat, 16 Jul 2011 17:36:32 +0000 (18:36 +0100)
 * Just use dev->si_drv1 for the strategy, disk ioctl and dump as the
   underlying device and 'dmv' is guaranteed not to go away. Keep the
   locked approach (dm_dev_lookup) for open, close, and mapper ioctls to
   ensure that we never rip out any node that's still in use.

 * This eliminates exclusive locking in the IO path, which should
   improve performance.

sys/dev/disk/dm/device-mapper.c
sys/dev/disk/dm/dm_dev.c
sys/dev/disk/dm/dm_ioctl.c

index 228821f..8812925 100644 (file)
@@ -349,10 +349,9 @@ disk_ioctl_switch(cdev_t dev, u_long cmd, void *data)
                dpart = (void *)data;
                bzero(dpart, sizeof(*dpart));
 
-               if ((dmv = dm_dev_lookup(NULL, NULL, minor(dev))) == NULL)
+               if ((dmv = dev->si_drv1) == NULL)
                        return ENODEV;
                if (dmv->diskp->d_info.d_media_blksize == 0) {
-                       dm_dev_unbusy(dmv);
                        return ENOTSUP;
                } else {
                        size = dm_table_size(&dmv->table_head);
@@ -362,7 +361,6 @@ disk_ioctl_switch(cdev_t dev, u_long cmd, void *data)
                        dpart->media_blksize = DEV_BSIZE;
                        dpart->fstype = FS_BSDFFS;
                }
-               dm_dev_unbusy(dmv);
                break;
        }
 
@@ -406,12 +404,7 @@ dmstrategy(struct dev_strategy_args *ap)
        dev_type = 0;
        issued_len = 0;
 
-       if ((dmv = dm_dev_lookup(NULL, NULL, minor(dev))) == NULL) {
-               bp->b_error = EIO;
-               bp->b_resid = bp->b_bcount;
-               biodone(bio);
-               return 0;
-       }
+       dmv = dev->si_drv1;
 
        switch(bp->b_cmd) {
        case BUF_CMD_READ:
@@ -424,7 +417,6 @@ dmstrategy(struct dev_strategy_args *ap)
                KKASSERT(buf_len == 0);
                break;
        default:
-               dm_dev_unbusy(dmv);
                bp->b_error = EIO;
                bp->b_resid = bp->b_bcount;
                biodone(bio);
@@ -434,7 +426,6 @@ dmstrategy(struct dev_strategy_args *ap)
        if (bypass == 0 &&
            bounds_check_with_mediasize(bio, DEV_BSIZE,
                                        dm_table_size(&dmv->table_head)) <= 0) {
-               dm_dev_unbusy(dmv);
                bp->b_resid = bp->b_bcount;
                biodone(bio);
                return 0;
@@ -498,7 +489,6 @@ dmstrategy(struct dev_strategy_args *ap)
                nestiobuf_error(bio, EINVAL);
        nestiobuf_start(bio);
        dm_table_release(&dmv->table_head, DM_TABLE_ACTIVE);
-       dm_dev_unbusy(dmv);
 
        return 0;
 }
@@ -527,9 +517,7 @@ dmdump(struct dev_dump_args *ap)
        dev_type = 0;
        issued_len = 0;
 
-       if ((dmv = dm_dev_lookup(NULL, NULL, minor(dev))) == NULL) {
-               return EIO;
-       }
+       dmv = dev->si_drv1;
 
        /* Select active table */
        tbl = dm_table_get_entry(&dmv->table_head, DM_TABLE_ACTIVE);
@@ -581,7 +569,6 @@ dmdump(struct dev_dump_args *ap)
 
 out:
        dm_table_release(&dmv->table_head, DM_TABLE_ACTIVE);
-       dm_dev_unbusy(dmv);
 
        return error;
 }
@@ -595,12 +582,10 @@ dmsize(struct dev_psize_args *ap)
 
        size = 0;
 
-       if ((dmv = dm_dev_lookup(NULL, NULL, minor(dev))) == NULL)
-                       return ENOENT;
+       if ((dmv = dev->si_drv1) == NULL)
+               return ENXIO;
 
        size = dm_table_size(&dmv->table_head);
-       dm_dev_unbusy(dmv);
-
        ap->a_result = (int64_t)size;
 
        return 0;
index f681ae6..a309471 100644 (file)
@@ -249,6 +249,9 @@ dm_dev_create(dm_dev_t **dmvp, const char *name, const char *uuid, int flags)
        dmv->devt = disk_create_named(name_buf, dm_minor, dmv->diskp, &dm_ops);
        reference_dev(dmv->devt);
 
+       dmv->devt->si_drv1 = dmv;
+       dmv->devt->si_drv2 = dmv->diskp;
+
        dmv->minor = minor(dmv->devt);
        udev_dict_set_cstr(dmv->devt, "subsystem", "disk");
 
index dcb005d..3430675 100644 (file)
@@ -325,7 +325,7 @@ dm_dev_remove_ioctl(prop_dictionary_t dm_dict)
 {
        dm_dev_t *dmv;
        const char *name, *uuid;
-       uint32_t flags, minor;
+       uint32_t flags, minor, is_open;
 
        flags = 0;
        name = NULL;
@@ -348,9 +348,11 @@ dm_dev_remove_ioctl(prop_dictionary_t dm_dict)
                return ENOENT;
        }
 
+       is_open = dmv->is_open;
+
        dm_dev_unbusy(dmv);
 
-       if (dmv->is_open)
+       if (is_open)
                return EBUSY;
 
        /*