aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-08-13 16:44:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-08-13 16:44:32 -0400
commitebcbf1664cda2bb504a3c5c1ced114daf4ddf54b (patch)
tree3390cc1b7a428078337aa2e737440f6479fd673e
parent6b476e114061599a6ab8d5464a5e16989cb98653 (diff)
parente162b219ae6a64be353f254bd4ba1c9627c67749 (diff)
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Pull xen block driver fixes from Jens Axboe: "A few small bug fixes for xen-blk{front,back} that have been sitting over my vacation" * 'for-linus' of git://git.kernel.dk/linux-block: xen-blkback: replace work_pending with work_busy in purge_persistent_gnt() xen-blkfront: don't add indirect pages to list when !feature_persistent xen-blkfront: introduce blkfront_gather_backend_features()
-rw-r--r--drivers/block/xen-blkback/blkback.c4
-rw-r--r--drivers/block/xen-blkfront.c128
2 files changed, 74 insertions, 58 deletions
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index ced96777b677..954c0029fb3b 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -369,8 +369,8 @@ static void purge_persistent_gnt(struct xen_blkif *blkif)
369 return; 369 return;
370 } 370 }
371 371
372 if (work_pending(&blkif->persistent_purge_work)) { 372 if (work_busy(&blkif->persistent_purge_work)) {
373 pr_alert_ratelimited("Scheduled work from previous purge is still pending, cannot purge list\n"); 373 pr_alert_ratelimited("Scheduled work from previous purge is still busy, cannot purge list\n");
374 return; 374 return;
375 } 375 }
376 376
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 6d89ed35d80c..7a8a73f1fc04 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -179,6 +179,7 @@ static DEFINE_SPINLOCK(minor_lock);
179 ((_segs + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME) 179 ((_segs + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME)
180 180
181static int blkfront_setup_indirect(struct blkfront_info *info); 181static int blkfront_setup_indirect(struct blkfront_info *info);
182static int blkfront_gather_backend_features(struct blkfront_info *info);
182 183
183static int get_id_from_freelist(struct blkfront_info *info) 184static int get_id_from_freelist(struct blkfront_info *info)
184{ 185{
@@ -1128,8 +1129,10 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
1128 * Add the used indirect page back to the list of 1129 * Add the used indirect page back to the list of
1129 * available pages for indirect grefs. 1130 * available pages for indirect grefs.
1130 */ 1131 */
1131 indirect_page = pfn_to_page(s->indirect_grants[i]->pfn); 1132 if (!info->feature_persistent) {
1132 list_add(&indirect_page->lru, &info->indirect_pages); 1133 indirect_page = pfn_to_page(s->indirect_grants[i]->pfn);
1134 list_add(&indirect_page->lru, &info->indirect_pages);
1135 }
1133 s->indirect_grants[i]->gref = GRANT_INVALID_REF; 1136 s->indirect_grants[i]->gref = GRANT_INVALID_REF;
1134 list_add_tail(&s->indirect_grants[i]->node, &info->grants); 1137 list_add_tail(&s->indirect_grants[i]->node, &info->grants);
1135 } 1138 }
@@ -1519,7 +1522,7 @@ static int blkif_recover(struct blkfront_info *info)
1519 info->shadow_free = info->ring.req_prod_pvt; 1522 info->shadow_free = info->ring.req_prod_pvt;
1520 info->shadow[BLK_RING_SIZE(info)-1].req.u.rw.id = 0x0fffffff; 1523 info->shadow[BLK_RING_SIZE(info)-1].req.u.rw.id = 0x0fffffff;
1521 1524
1522 rc = blkfront_setup_indirect(info); 1525 rc = blkfront_gather_backend_features(info);
1523 if (rc) { 1526 if (rc) {
1524 kfree(copy); 1527 kfree(copy);
1525 return rc; 1528 return rc;
@@ -1720,20 +1723,13 @@ static void blkfront_setup_discard(struct blkfront_info *info)
1720 1723
1721static int blkfront_setup_indirect(struct blkfront_info *info) 1724static int blkfront_setup_indirect(struct blkfront_info *info)
1722{ 1725{
1723 unsigned int indirect_segments, segs; 1726 unsigned int segs;
1724 int err, i; 1727 int err, i;
1725 1728
1726 err = xenbus_gather(XBT_NIL, info->xbdev->otherend, 1729 if (info->max_indirect_segments == 0)
1727 "feature-max-indirect-segments", "%u", &indirect_segments,
1728 NULL);
1729 if (err) {
1730 info->max_indirect_segments = 0;
1731 segs = BLKIF_MAX_SEGMENTS_PER_REQUEST; 1730 segs = BLKIF_MAX_SEGMENTS_PER_REQUEST;
1732 } else { 1731 else
1733 info->max_indirect_segments = min(indirect_segments,
1734 xen_blkif_max_segments);
1735 segs = info->max_indirect_segments; 1732 segs = info->max_indirect_segments;
1736 }
1737 1733
1738 err = fill_grant_buffer(info, (segs + INDIRECT_GREFS(segs)) * BLK_RING_SIZE(info)); 1734 err = fill_grant_buffer(info, (segs + INDIRECT_GREFS(segs)) * BLK_RING_SIZE(info));
1739 if (err) 1735 if (err)
@@ -1797,6 +1793,68 @@ out_of_memory:
1797} 1793}
1798 1794
1799/* 1795/*
1796 * Gather all backend feature-*
1797 */
1798static int blkfront_gather_backend_features(struct blkfront_info *info)
1799{
1800 int err;
1801 int barrier, flush, discard, persistent;
1802 unsigned int indirect_segments;
1803
1804 info->feature_flush = 0;
1805
1806 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
1807 "feature-barrier", "%d", &barrier,
1808 NULL);
1809
1810 /*
1811 * If there's no "feature-barrier" defined, then it means
1812 * we're dealing with a very old backend which writes
1813 * synchronously; nothing to do.
1814 *
1815 * If there are barriers, then we use flush.
1816 */
1817 if (!err && barrier)
1818 info->feature_flush = REQ_FLUSH | REQ_FUA;
1819 /*
1820 * And if there is "feature-flush-cache" use that above
1821 * barriers.
1822 */
1823 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
1824 "feature-flush-cache", "%d", &flush,
1825 NULL);
1826
1827 if (!err && flush)
1828 info->feature_flush = REQ_FLUSH;
1829
1830 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
1831 "feature-discard", "%d", &discard,
1832 NULL);
1833
1834 if (!err && discard)
1835 blkfront_setup_discard(info);
1836
1837 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
1838 "feature-persistent", "%u", &persistent,
1839 NULL);
1840 if (err)
1841 info->feature_persistent = 0;
1842 else
1843 info->feature_persistent = persistent;
1844
1845 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
1846 "feature-max-indirect-segments", "%u", &indirect_segments,
1847 NULL);
1848 if (err)
1849 info->max_indirect_segments = 0;
1850 else
1851 info->max_indirect_segments = min(indirect_segments,
1852 xen_blkif_max_segments);
1853
1854 return blkfront_setup_indirect(info);
1855}
1856
1857/*
1800 * Invoked when the backend is finally 'ready' (and has told produced 1858 * Invoked when the backend is finally 'ready' (and has told produced
1801 * the details about the physical device - #sectors, size, etc). 1859 * the details about the physical device - #sectors, size, etc).
1802 */ 1860 */
@@ -1807,7 +1865,6 @@ static void blkfront_connect(struct blkfront_info *info)
1807 unsigned int physical_sector_size; 1865 unsigned int physical_sector_size;
1808 unsigned int binfo; 1866 unsigned int binfo;
1809 int err; 1867 int err;
1810 int barrier, flush, discard, persistent;
1811 1868
1812 switch (info->connected) { 1869 switch (info->connected) {
1813 case BLKIF_STATE_CONNECTED: 1870 case BLKIF_STATE_CONNECTED:
@@ -1864,48 +1921,7 @@ static void blkfront_connect(struct blkfront_info *info)
1864 if (err != 1) 1921 if (err != 1)
1865 physical_sector_size = sector_size; 1922 physical_sector_size = sector_size;
1866 1923
1867 info->feature_flush = 0; 1924 err = blkfront_gather_backend_features(info);
1868
1869 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
1870 "feature-barrier", "%d", &barrier,
1871 NULL);
1872
1873 /*
1874 * If there's no "feature-barrier" defined, then it means
1875 * we're dealing with a very old backend which writes
1876 * synchronously; nothing to do.
1877 *
1878 * If there are barriers, then we use flush.
1879 */
1880 if (!err && barrier)
1881 info->feature_flush = REQ_FLUSH | REQ_FUA;
1882 /*
1883 * And if there is "feature-flush-cache" use that above
1884 * barriers.
1885 */
1886 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
1887 "feature-flush-cache", "%d", &flush,
1888 NULL);
1889
1890 if (!err && flush)
1891 info->feature_flush = REQ_FLUSH;
1892
1893 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
1894 "feature-discard", "%d", &discard,
1895 NULL);
1896
1897 if (!err && discard)
1898 blkfront_setup_discard(info);
1899
1900 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
1901 "feature-persistent", "%u", &persistent,
1902 NULL);
1903 if (err)
1904 info->feature_persistent = 0;
1905 else
1906 info->feature_persistent = persistent;
1907
1908 err = blkfront_setup_indirect(info);
1909 if (err) { 1925 if (err) {
1910 xenbus_dev_fatal(info->xbdev, err, "setup_indirect at %s", 1926 xenbus_dev_fatal(info->xbdev, err, "setup_indirect at %s",
1911 info->xbdev->otherend); 1927 info->xbdev->otherend);