diff options
Diffstat (limited to 'drivers/block/xen-blkfront.c')
-rw-r--r-- | drivers/block/xen-blkfront.c | 74 |
1 files changed, 45 insertions, 29 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 8a8dc91c39f7..83eb9e6bf8b0 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -1873,6 +1873,43 @@ again: | |||
1873 | return err; | 1873 | return err; |
1874 | } | 1874 | } |
1875 | 1875 | ||
1876 | static int negotiate_mq(struct blkfront_info *info) | ||
1877 | { | ||
1878 | unsigned int backend_max_queues = 0; | ||
1879 | int err; | ||
1880 | unsigned int i; | ||
1881 | |||
1882 | BUG_ON(info->nr_rings); | ||
1883 | |||
1884 | /* Check if backend supports multiple queues. */ | ||
1885 | err = xenbus_scanf(XBT_NIL, info->xbdev->otherend, | ||
1886 | "multi-queue-max-queues", "%u", &backend_max_queues); | ||
1887 | if (err < 0) | ||
1888 | backend_max_queues = 1; | ||
1889 | |||
1890 | info->nr_rings = min(backend_max_queues, xen_blkif_max_queues); | ||
1891 | /* We need at least one ring. */ | ||
1892 | if (!info->nr_rings) | ||
1893 | info->nr_rings = 1; | ||
1894 | |||
1895 | info->rinfo = kzalloc(sizeof(struct blkfront_ring_info) * info->nr_rings, GFP_KERNEL); | ||
1896 | if (!info->rinfo) { | ||
1897 | xenbus_dev_fatal(info->xbdev, -ENOMEM, "allocating ring_info structure"); | ||
1898 | return -ENOMEM; | ||
1899 | } | ||
1900 | |||
1901 | for (i = 0; i < info->nr_rings; i++) { | ||
1902 | struct blkfront_ring_info *rinfo; | ||
1903 | |||
1904 | rinfo = &info->rinfo[i]; | ||
1905 | INIT_LIST_HEAD(&rinfo->indirect_pages); | ||
1906 | INIT_LIST_HEAD(&rinfo->grants); | ||
1907 | rinfo->dev_info = info; | ||
1908 | INIT_WORK(&rinfo->work, blkif_restart_queue); | ||
1909 | spin_lock_init(&rinfo->ring_lock); | ||
1910 | } | ||
1911 | return 0; | ||
1912 | } | ||
1876 | /** | 1913 | /** |
1877 | * Entry point to this code when a new device is created. Allocate the basic | 1914 | * Entry point to this code when a new device is created. Allocate the basic |
1878 | * structures and the ring buffer for communication with the backend, and | 1915 | * structures and the ring buffer for communication with the backend, and |
@@ -1883,9 +1920,7 @@ static int blkfront_probe(struct xenbus_device *dev, | |||
1883 | const struct xenbus_device_id *id) | 1920 | const struct xenbus_device_id *id) |
1884 | { | 1921 | { |
1885 | int err, vdevice; | 1922 | int err, vdevice; |
1886 | unsigned int r_index; | ||
1887 | struct blkfront_info *info; | 1923 | struct blkfront_info *info; |
1888 | unsigned int backend_max_queues = 0; | ||
1889 | 1924 | ||
1890 | /* FIXME: Use dynamic device id if this is not set. */ | 1925 | /* FIXME: Use dynamic device id if this is not set. */ |
1891 | err = xenbus_scanf(XBT_NIL, dev->nodename, | 1926 | err = xenbus_scanf(XBT_NIL, dev->nodename, |
@@ -1936,33 +1971,10 @@ static int blkfront_probe(struct xenbus_device *dev, | |||
1936 | } | 1971 | } |
1937 | 1972 | ||
1938 | info->xbdev = dev; | 1973 | info->xbdev = dev; |
1939 | /* Check if backend supports multiple queues. */ | 1974 | err = negotiate_mq(info); |
1940 | err = xenbus_scanf(XBT_NIL, info->xbdev->otherend, | 1975 | if (err) { |
1941 | "multi-queue-max-queues", "%u", &backend_max_queues); | ||
1942 | if (err < 0) | ||
1943 | backend_max_queues = 1; | ||
1944 | |||
1945 | info->nr_rings = min(backend_max_queues, xen_blkif_max_queues); | ||
1946 | /* We need at least one ring. */ | ||
1947 | if (!info->nr_rings) | ||
1948 | info->nr_rings = 1; | ||
1949 | |||
1950 | info->rinfo = kzalloc(sizeof(struct blkfront_ring_info) * info->nr_rings, GFP_KERNEL); | ||
1951 | if (!info->rinfo) { | ||
1952 | xenbus_dev_fatal(dev, -ENOMEM, "allocating ring_info structure"); | ||
1953 | kfree(info); | 1976 | kfree(info); |
1954 | return -ENOMEM; | 1977 | return err; |
1955 | } | ||
1956 | |||
1957 | for (r_index = 0; r_index < info->nr_rings; r_index++) { | ||
1958 | struct blkfront_ring_info *rinfo; | ||
1959 | |||
1960 | rinfo = &info->rinfo[r_index]; | ||
1961 | INIT_LIST_HEAD(&rinfo->indirect_pages); | ||
1962 | INIT_LIST_HEAD(&rinfo->grants); | ||
1963 | rinfo->dev_info = info; | ||
1964 | INIT_WORK(&rinfo->work, blkif_restart_queue); | ||
1965 | spin_lock_init(&rinfo->ring_lock); | ||
1966 | } | 1978 | } |
1967 | 1979 | ||
1968 | mutex_init(&info->mutex); | 1980 | mutex_init(&info->mutex); |
@@ -2123,12 +2135,16 @@ static int blkif_recover(struct blkfront_info *info) | |||
2123 | static int blkfront_resume(struct xenbus_device *dev) | 2135 | static int blkfront_resume(struct xenbus_device *dev) |
2124 | { | 2136 | { |
2125 | struct blkfront_info *info = dev_get_drvdata(&dev->dev); | 2137 | struct blkfront_info *info = dev_get_drvdata(&dev->dev); |
2126 | int err; | 2138 | int err = 0; |
2127 | 2139 | ||
2128 | dev_dbg(&dev->dev, "blkfront_resume: %s\n", dev->nodename); | 2140 | dev_dbg(&dev->dev, "blkfront_resume: %s\n", dev->nodename); |
2129 | 2141 | ||
2130 | blkif_free(info, info->connected == BLKIF_STATE_CONNECTED); | 2142 | blkif_free(info, info->connected == BLKIF_STATE_CONNECTED); |
2131 | 2143 | ||
2144 | err = negotiate_mq(info); | ||
2145 | if (err) | ||
2146 | return err; | ||
2147 | |||
2132 | err = talk_to_blkback(dev, info); | 2148 | err = talk_to_blkback(dev, info); |
2133 | 2149 | ||
2134 | /* | 2150 | /* |