Merge branch 'remotes/lorenzo/pci/cadence'
[linux-2.6-microblaze.git] / block / blk-sysfs.c
index 9bfa3ea..46f5198 100644 (file)
@@ -482,7 +482,6 @@ static ssize_t queue_wb_lat_store(struct request_queue *q, const char *page,
        blk_mq_quiesce_queue(q);
 
        wbt_set_min_lat(q, val);
-       wbt_update_limits(q);
 
        blk_mq_unquiesce_queue(q);
        blk_mq_unfreeze_queue(q);
@@ -941,14 +940,14 @@ int blk_register_queue(struct gendisk *disk)
        int ret;
        struct device *dev = disk_to_dev(disk);
        struct request_queue *q = disk->queue;
+       bool has_elevator = false;
 
        if (WARN_ON(!q))
                return -ENXIO;
 
-       WARN_ONCE(test_bit(QUEUE_FLAG_REGISTERED, &q->queue_flags),
+       WARN_ONCE(blk_queue_registered(q),
                  "%s is registering an already registered queue\n",
                  kobject_name(&dev->kobj));
-       blk_queue_flag_set(QUEUE_FLAG_REGISTERED, q);
 
        /*
         * SCSI probing may synchronously create and destroy a lot of
@@ -968,8 +967,7 @@ int blk_register_queue(struct gendisk *disk)
        if (ret)
                return ret;
 
-       /* Prevent changes through sysfs until registration is completed. */
-       mutex_lock(&q->sysfs_lock);
+       mutex_lock(&q->sysfs_dir_lock);
 
        ret = kobject_add(&q->kobj, kobject_get(&dev->kobj), "%s", "queue");
        if (ret < 0) {
@@ -990,26 +988,33 @@ int blk_register_queue(struct gendisk *disk)
                blk_mq_debugfs_register(q);
        }
 
-       kobject_uevent(&q->kobj, KOBJ_ADD);
-
-       wbt_enable_default(q);
-
-       blk_throtl_register_queue(q);
-
+       mutex_lock(&q->sysfs_lock);
        if (q->elevator) {
-               ret = elv_register_queue(q);
+               ret = elv_register_queue(q, false);
                if (ret) {
                        mutex_unlock(&q->sysfs_lock);
-                       kobject_uevent(&q->kobj, KOBJ_REMOVE);
+                       mutex_unlock(&q->sysfs_dir_lock);
                        kobject_del(&q->kobj);
                        blk_trace_remove_sysfs(dev);
                        kobject_put(&dev->kobj);
                        return ret;
                }
+               has_elevator = true;
        }
+
+       blk_queue_flag_set(QUEUE_FLAG_REGISTERED, q);
+       wbt_enable_default(q);
+       blk_throtl_register_queue(q);
+
+       /* Now everything is ready and send out KOBJ_ADD uevent */
+       kobject_uevent(&q->kobj, KOBJ_ADD);
+       if (has_elevator)
+               kobject_uevent(&q->elevator->kobj, KOBJ_ADD);
+       mutex_unlock(&q->sysfs_lock);
+
        ret = 0;
 unlock:
-       mutex_unlock(&q->sysfs_lock);
+       mutex_unlock(&q->sysfs_dir_lock);
        return ret;
 }
 EXPORT_SYMBOL_GPL(blk_register_queue);
@@ -1029,7 +1034,7 @@ void blk_unregister_queue(struct gendisk *disk)
                return;
 
        /* Return early if disk->queue was never registered. */
-       if (!test_bit(QUEUE_FLAG_REGISTERED, &q->queue_flags))
+       if (!blk_queue_registered(q))
                return;
 
        /*
@@ -1038,16 +1043,16 @@ void blk_unregister_queue(struct gendisk *disk)
         * concurrent elv_iosched_store() calls.
         */
        mutex_lock(&q->sysfs_lock);
-
        blk_queue_flag_clear(QUEUE_FLAG_REGISTERED, q);
+       mutex_unlock(&q->sysfs_lock);
 
+       mutex_lock(&q->sysfs_dir_lock);
        /*
         * Remove the sysfs attributes before unregistering the queue data
         * structures that can be modified through sysfs.
         */
        if (queue_is_mq(q))
                blk_mq_unregister_dev(disk_to_dev(disk), q);
-       mutex_unlock(&q->sysfs_lock);
 
        kobject_uevent(&q->kobj, KOBJ_REMOVE);
        kobject_del(&q->kobj);
@@ -1057,6 +1062,7 @@ void blk_unregister_queue(struct gendisk *disk)
        if (q->elevator)
                elv_unregister_queue(q);
        mutex_unlock(&q->sysfs_lock);
+       mutex_unlock(&q->sysfs_dir_lock);
 
        kobject_put(&disk_to_dev(disk)->kobj);
 }