diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-08-13 16:44:32 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-08-13 16:44:32 -0400 |
| commit | ebcbf1664cda2bb504a3c5c1ced114daf4ddf54b (patch) | |
| tree | 3390cc1b7a428078337aa2e737440f6479fd673e | |
| parent | 6b476e114061599a6ab8d5464a5e16989cb98653 (diff) | |
| parent | e162b219ae6a64be353f254bd4ba1c9627c67749 (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.c | 4 | ||||
| -rw-r--r-- | drivers/block/xen-blkfront.c | 128 |
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 | ||
| 181 | static int blkfront_setup_indirect(struct blkfront_info *info); | 181 | static int blkfront_setup_indirect(struct blkfront_info *info); |
| 182 | static int blkfront_gather_backend_features(struct blkfront_info *info); | ||
| 182 | 183 | ||
| 183 | static int get_id_from_freelist(struct blkfront_info *info) | 184 | static 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 | ||
| 1721 | static int blkfront_setup_indirect(struct blkfront_info *info) | 1724 | static 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 | */ | ||
| 1798 | static 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); |
