History

Merge tag 'for-linus-5.6b-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen fixes from Juergen Gross: "Four fixes and a small cleanup patch: - two fixes by Dongli Zhang fixing races in the xenbus driver - two fixes by me fixing issues introduced in 5.6 - a small cleanup by Gustavo Silva replacing a zero-length array with a flexible-array" * tag 'for-linus-5.6b-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen/blkfront: fix ring info addressing xen/xenbus: fix locking xenbus: req->err should be updated before req->state xenbus: req->body should be updated before req->state xen: Replace zero-length array with flexible-array member

Linus Torvalds committed 6 years ago

Commit cbee7c82 parents fa883d6 4ab50af8 files · +64 −51Browse files

Unified · Split

8 files
  1. drivers/block/xen-blkfront.c +42 −38
  2. drivers/xen/xen-pciback/pciback.h +1 −1
  3. drivers/xen/xenbus/xenbus_comms.c +4 −0
  4. drivers/xen/xenbus/xenbus_probe.c +5 −5
  5. drivers/xen/xenbus/xenbus_probe_backend.c +3 −2
  6. drivers/xen/xenbus/xenbus_xs.c +6 −3
  7. include/xen/interface/io/tpmif.h +1 −1
  8. include/xen/xenbus.h +2 −1
drivers/block/xen-blkfront.c+42−38
@@ -213,6 +213,7 @@ struct blkfront_info · 212 unmodified lines
213213 struct blk_mq_tag_set tag_set;
214214 struct blkfront_ring_info *rinfo;
215215 unsigned int nr_rings;
216+ unsigned int rinfo_size;
216217 /* Save uncomplete reqs and bios for migration. */
217218 struct list_head requests;
218219 struct bio_list bio_list;
@@ -259,6 +260,18 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo); · 40 unmodified lines
259260 static void blkfront_gather_backend_features(struct blkfront_info *info);
260261 static int negotiate_mq(struct blkfront_info *info);
261262
263+#define for_each_rinfo(info, ptr, idx) \
264+ for ((ptr) = (info)->rinfo, (idx) = 0; \
265+ (idx) < (info)->nr_rings; \
266+ (idx)++, (ptr) = (void *)(ptr) + (info)->rinfo_size)
267+
268+static inline struct blkfront_ring_info *
269+get_rinfo(const struct blkfront_info *info, unsigned int i)
270+{
271+ BUG_ON(i >= info->nr_rings);
272+ return (void *)info->rinfo + i * info->rinfo_size;
273+}
274+
262275 static int get_id_from_freelist(struct blkfront_ring_info *rinfo)
263276 {
264277 unsigned long free = rinfo->shadow_free;
@@ -883,8 +896,7 @@ static blk_status_t blkif_queue_rq(struct blk_mq_hw_ctx *hctx, · 618 unmodified lines
883896 struct blkfront_info *info = hctx->queue->queuedata;
884897 struct blkfront_ring_info *rinfo = NULL;
885898
886− BUG_ON(info->nr_rings <= qid);
887− rinfo = &info->rinfo[qid];
899+ rinfo = get_rinfo(info, qid);
888900 blk_mq_start_request(qd->rq);
889901 spin_lock_irqsave(&rinfo->ring_lock, flags);
890902 if (RING_FULL(&rinfo->ring))
@@ -1181,6 +1193,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, · 290 unmodified lines
11811193 static void xlvbd_release_gendisk(struct blkfront_info *info)
11821194 {
11831195 unsigned int minor, nr_minors, i;
1196+ struct blkfront_ring_info *rinfo;
11841197
11851198 if (info->rq == NULL)
11861199 return;
@@ -1188,9 +1201,7 @@ static void xlvbd_release_gendisk(struct blkfront_info *info) · 1 unmodified line
11881201 /* No more blkif_request(). */
11891202 blk_mq_stop_hw_queues(info->rq);
11901203
1191− for (i = 0; i < info->nr_rings; i++) {
1192− struct blkfront_ring_info *rinfo = &info->rinfo[i];
1193−
1204+ for_each_rinfo(info, rinfo, i) {
11941205 /* No more gnttab callback work. */
11951206 gnttab_cancel_free_callback(&rinfo->callback);
11961207
@@ -1339,6 +1350,7 @@ free_shadow: · 142 unmodified lines
13391350 static void blkif_free(struct blkfront_info *info, int suspend)
13401351 {
13411352 unsigned int i;
1353+ struct blkfront_ring_info *rinfo;
13421354
13431355 /* Prevent new requests being issued until we fix things up. */
13441356 info->connected = suspend ?
@@ -1347,8 +1359,8 @@ static void blkif_free(struct blkfront_info *info, int suspend) · 2 unmodified lines
13471359 if (info->rq)
13481360 blk_mq_stop_hw_queues(info->rq);
13491361
1350− for (i = 0; i < info->nr_rings; i++)
1351− blkif_free_ring(&info->rinfo[i]);
1362+ for_each_rinfo(info, rinfo, i)
1363+ blkif_free_ring(rinfo);
13521364
13531365 kvfree(info->rinfo);
13541366 info->rinfo = NULL;
@@ -1775,6 +1787,7 @@ static int talk_to_blkback(struct xenbus_device *dev, · 420 unmodified lines
17751787 int err;
17761788 unsigned int i, max_page_order;
17771789 unsigned int ring_page_order;
1790+ struct blkfront_ring_info *rinfo;
17781791
17791792 if (!info)
17801793 return -ENODEV;
@@ -1788,9 +1801,7 @@ static int talk_to_blkback(struct xenbus_device *dev, · 7 unmodified lines
17881801 if (err)
17891802 goto destroy_blkring;
17901803
1791− for (i = 0; i < info->nr_rings; i++) {
1792− struct blkfront_ring_info *rinfo = &info->rinfo[i];
1793−
1804+ for_each_rinfo(info, rinfo, i) {
17941805 /* Create shared ring, alloc event channel. */
17951806 err = setup_blkring(dev, rinfo);
17961807 if (err)
@@ -1815,7 +1826,7 @@ again: · 18 unmodified lines
18151826
18161827 /* We already got the number of queues/rings in _probe */
18171828 if (info->nr_rings == 1) {
1818− err = write_per_ring_nodes(xbt, &info->rinfo[0], dev->nodename);
1829+ err = write_per_ring_nodes(xbt, info->rinfo, dev->nodename);
18191830 if (err)
18201831 goto destroy_blkring;
18211832 } else {
@@ -1837,10 +1848,10 @@ again: · 15 unmodified lines
18371848 goto abort_transaction;
18381849 }
18391850
1840− for (i = 0; i < info->nr_rings; i++) {
1851+ for_each_rinfo(info, rinfo, i) {
18411852 memset(path, 0, pathsize);
18421853 snprintf(path, pathsize, "%s/queue-%u", dev->nodename, i);
1843− err = write_per_ring_nodes(xbt, &info->rinfo[i], path);
1854+ err = write_per_ring_nodes(xbt, rinfo, path);
18441855 if (err) {
18451856 kfree(path);
18461857 goto destroy_blkring;
@@ -1868,9 +1879,8 @@ again: · 21 unmodified lines
18681879 goto destroy_blkring;
18691880 }
18701881
1871− for (i = 0; i < info->nr_rings; i++) {
1882+ for_each_rinfo(info, rinfo, i) {
18721883 unsigned int j;
1873− struct blkfront_ring_info *rinfo = &info->rinfo[i];
18741884
18751885 for (j = 0; j < BLK_RING_SIZE(info); j++)
18761886 rinfo->shadow[j].req.u.rw.id = j + 1;
@@ -1900,6 +1910,7 @@ static int negotiate_mq(struct blkfront_info *info) · 23 unmodified lines
19001910 {
19011911 unsigned int backend_max_queues;
19021912 unsigned int i;
1913+ struct blkfront_ring_info *rinfo;
19031914
19041915 BUG_ON(info->nr_rings);
19051916
@@ -1911,20 +1922,16 @@ static int negotiate_mq(struct blkfront_info *info) · 5 unmodified lines
19111922 if (!info->nr_rings)
19121923 info->nr_rings = 1;
19131924
1914− info->rinfo = kvcalloc(info->nr_rings,
1915− struct_size(info->rinfo, shadow,
1916− BLK_RING_SIZE(info)),
1917− GFP_KERNEL);
1925+ info->rinfo_size = struct_size(info->rinfo, shadow,
1926+ BLK_RING_SIZE(info));
1927+ info->rinfo = kvcalloc(info->nr_rings, info->rinfo_size, GFP_KERNEL);
19181928 if (!info->rinfo) {
19191929 xenbus_dev_fatal(info->xbdev, -ENOMEM, "allocating ring_info structure");
19201930 info->nr_rings = 0;
19211931 return -ENOMEM;
19221932 }
19231933
1924− for (i = 0; i < info->nr_rings; i++) {
1925− struct blkfront_ring_info *rinfo;
1926−
1927− rinfo = &info->rinfo[i];
1934+ for_each_rinfo(info, rinfo, i) {
19281935 INIT_LIST_HEAD(&rinfo->indirect_pages);
19291936 INIT_LIST_HEAD(&rinfo->grants);
19301937 rinfo->dev_info = info;
@@ -2017,6 +2024,7 @@ static int blkif_recover(struct blkfront_info *info) · 86 unmodified lines
20172024 int rc;
20182025 struct bio *bio;
20192026 unsigned int segs;
2027+ struct blkfront_ring_info *rinfo;
20202028
20212029 blkfront_gather_backend_features(info);
20222030 /* Reset limits changed by blk_mq_update_nr_hw_queues(). */
@@ -2024,9 +2032,7 @@ static int blkif_recover(struct blkfront_info *info) · 1 unmodified line
20242032 segs = info->max_indirect_segments ? : BLKIF_MAX_SEGMENTS_PER_REQUEST;
20252033 blk_queue_max_segments(info->rq, segs / GRANTS_PER_PSEG);
20262034
2027− for (r_index = 0; r_index < info->nr_rings; r_index++) {
2028− struct blkfront_ring_info *rinfo = &info->rinfo[r_index];
2029−
2035+ for_each_rinfo(info, rinfo, r_index) {
20302036 rc = blkfront_setup_indirect(rinfo);
20312037 if (rc)
20322038 return rc;
@@ -2036,10 +2042,7 @@ static int blkif_recover(struct blkfront_info *info) · 3 unmodified lines
20362042 /* Now safe for us to use the shared ring */
20372043 info->connected = BLKIF_STATE_CONNECTED;
20382044
2039− for (r_index = 0; r_index < info->nr_rings; r_index++) {
2040− struct blkfront_ring_info *rinfo;
2041−
2042− rinfo = &info->rinfo[r_index];
2045+ for_each_rinfo(info, rinfo, r_index) {
20432046 /* Kick any other new requests queued since we resumed */
20442047 kick_pending_request_queues(rinfo);
20452048 }
@@ -2072,13 +2075,13 @@ static int blkfront_resume(struct xenbus_device *dev) · 26 unmodified lines
20722075 struct blkfront_info *info = dev_get_drvdata(&dev->dev);
20732076 int err = 0;
20742077 unsigned int i, j;
2078+ struct blkfront_ring_info *rinfo;
20752079
20762080 dev_dbg(&dev->dev, "blkfront_resume: %s\n", dev->nodename);
20772081
20782082 bio_list_init(&info->bio_list);
20792083 INIT_LIST_HEAD(&info->requests);
2080− for (i = 0; i < info->nr_rings; i++) {
2081− struct blkfront_ring_info *rinfo = &info->rinfo[i];
2084+ for_each_rinfo(info, rinfo, i) {
20822085 struct bio_list merge_bio;
20832086 struct blk_shadow *shadow = rinfo->shadow;
20842087
@@ -2337,6 +2340,7 @@ static void blkfront_connect(struct blkfront_info *info) · 252 unmodified lines
23372340 unsigned int binfo;
23382341 char *envp[] = { "RESIZE=1", NULL };
23392342 int err, i;
2343+ struct blkfront_ring_info *rinfo;
23402344
23412345 switch (info->connected) {
23422346 case BLKIF_STATE_CONNECTED:
@@ -2394,8 +2398,8 @@ static void blkfront_connect(struct blkfront_info *info) · 51 unmodified lines
23942398 "physical-sector-size",
23952399 sector_size);
23962400 blkfront_gather_backend_features(info);
2397− for (i = 0; i < info->nr_rings; i++) {
2398− err = blkfront_setup_indirect(&info->rinfo[i]);
2401+ for_each_rinfo(info, rinfo, i) {
2402+ err = blkfront_setup_indirect(rinfo);
23992403 if (err) {
24002404 xenbus_dev_fatal(info->xbdev, err, "setup_indirect at %s",
24012405 info->xbdev->otherend);
@@ -2416,8 +2420,8 @@ static void blkfront_connect(struct blkfront_info *info) · 14 unmodified lines
24162420
24172421 /* Kick pending requests. */
24182422 info->connected = BLKIF_STATE_CONNECTED;
2419− for (i = 0; i < info->nr_rings; i++)
2420− kick_pending_request_queues(&info->rinfo[i]);
2423+ for_each_rinfo(info, rinfo, i)
2424+ kick_pending_request_queues(rinfo);
24212425
24222426 device_add_disk(&info->xbdev->dev, info->gd, NULL);
24232427
@@ -2652,9 +2656,9 @@ static void purge_persistent_grants(struct blkfront_info *info) · 228 unmodified lines
26522656 {
26532657 unsigned int i;
26542658 unsigned long flags;
2659+ struct blkfront_ring_info *rinfo;
26552660
2656− for (i = 0; i < info->nr_rings; i++) {
2657− struct blkfront_ring_info *rinfo = &info->rinfo[i];
2661+ for_each_rinfo(info, rinfo, i) {
26582662 struct grant *gnt_list_entry, *tmp;
26592663
26602664 spin_lock_irqsave(&rinfo->ring_lock, flags);
drivers/xen/xen-pciback/pciback.h+1−1
@@ -52,7 +52,7 @@ struct xen_pcibk_dev_data { · 51 unmodified lines
5252 unsigned int ack_intr:1; /* .. and ACK-ing */
5353 unsigned long handled;
5454 unsigned int irq; /* Saved in case device transitions to MSI/MSI-X */
55− char irq_name[0]; /* xen-pcibk[000:04:00.0] */
55+ char irq_name[]; /* xen-pcibk[000:04:00.0] */
5656 };
5757
5858 /* Used by XenBus and xen_pcibk_ops.c */
drivers/xen/xenbus/xenbus_comms.c+4−0
@@ -313,6 +313,8 @@ static int process_msg(void) · 312 unmodified lines
313313 req->msg.type = state.msg.type;
314314 req->msg.len = state.msg.len;
315315 req->body = state.body;
316+ /* write body, then update state */
317+ virt_wmb();
316318 req->state = xb_req_state_got_reply;
317319 req->cb(req);
318320 } else
@@ -395,6 +397,8 @@ static int process_writes(void) · 76 unmodified lines
395397 if (state.req->state == xb_req_state_aborted)
396398 kfree(state.req);
397399 else {
400+ /* write err, then update state */
401+ virt_wmb();
398402 state.req->state = xb_req_state_got_reply;
399403 wake_up(&state.req->wq);
400404 }
drivers/xen/xenbus/xenbus_probe.c+5−5
@@ -239,9 +239,9 @@ int xenbus_dev_probe(struct device *_dev) · 238 unmodified lines
239239 goto fail;
240240 }
241241
242− spin_lock(&dev->reclaim_lock);
242+ down(&dev->reclaim_sem);
243243 err = drv->probe(dev, id);
244− spin_unlock(&dev->reclaim_lock);
244+ up(&dev->reclaim_sem);
245245 if (err)
246246 goto fail_put;
247247
@@ -271,9 +271,9 @@ int xenbus_dev_remove(struct device *_dev) · 23 unmodified lines
271271 free_otherend_watch(dev);
272272
273273 if (drv->remove) {
274− spin_lock(&dev->reclaim_lock);
274+ down(&dev->reclaim_sem);
275275 drv->remove(dev);
276− spin_unlock(&dev->reclaim_lock);
276+ up(&dev->reclaim_sem);
277277 }
278278
279279 module_put(drv->driver.owner);
@@ -473,7 +473,7 @@ int xenbus_probe_node(struct xen_bus_type *bus, · 193 unmodified lines
473473 goto fail;
474474
475475 dev_set_name(&xendev->dev, "%s", devname);
476− spin_lock_init(&xendev->reclaim_lock);
476+ sema_init(&xendev->reclaim_sem, 1);
477477
478478 /* Register with generic device framework. */
479479 err = device_register(&xendev->dev);
drivers/xen/xenbus/xenbus_probe_backend.c+3−2
@@ -45,6 +45,7 @@ · 44 unmodified lines
4545 #include <linux/mm.h>
4646 #include <linux/notifier.h>
4747 #include <linux/export.h>
48+#include <linux/semaphore.h>
4849
4950 #include <asm/page.h>
5051 #include <asm/pgtable.h>
@@ -257,10 +258,10 @@ static int backend_reclaim_memory(struct device *dev, void *data) · 206 unmodified lines
257258 drv = to_xenbus_driver(dev->driver);
258259 if (drv && drv->reclaim_memory) {
259260 xdev = to_xenbus_device(dev);
260− if (!spin_trylock(&xdev->reclaim_lock))
261+ if (down_trylock(&xdev->reclaim_sem))
261262 return 0;
262263 drv->reclaim_memory(xdev);
263− spin_unlock(&xdev->reclaim_lock);
264+ up(&xdev->reclaim_sem);
264265 }
265266 return 0;
266267 }
drivers/xen/xenbus/xenbus_xs.c+6−3
@@ -191,8 +191,11 @@ static bool xenbus_ok(void) · 190 unmodified lines
191191
192192 static bool test_reply(struct xb_req_data *req)
193193 {
194− if (req->state == xb_req_state_got_reply || !xenbus_ok())
194+ if (req->state == xb_req_state_got_reply || !xenbus_ok()) {
195+ /* read req->state before all other fields */
196+ virt_rmb();
195197 return true;
198+ }
196199
197200 /* Make sure to reread req->state each time. */
198201 barrier();
@@ -202,7 +205,7 @@ static bool test_reply(struct xb_req_data *req) · 3 unmodified lines
202205
203206 static void *read_reply(struct xb_req_data *req)
204207 {
205− while (req->state != xb_req_state_got_reply) {
208+ do {
206209 wait_event(req->wq, test_reply(req));
207210
208211 if (!xenbus_ok())
@@ -216,7 +219,7 @@ static void *read_reply(struct xb_req_data *req) · 7 unmodified lines
216219 if (req->err)
217220 return ERR_PTR(req->err);
218221
219− }
222+ } while (req->state != xb_req_state_got_reply);
220223
221224 return req->body;
222225 }
include/xen/interface/io/tpmif.h+1−1
@@ -46,7 +46,7 @@ struct vtpm_shared_page { · 45 unmodified lines
4646 uint8_t pad;
4747
4848 uint8_t nr_extra_pages; /* extra pages for long packets; may be zero */
49− uint32_t extra_pages[0]; /* grant IDs; length in nr_extra_pages */
49+ uint32_t extra_pages[]; /* grant IDs; length in nr_extra_pages */
5050 };
5151
5252 #endif
include/xen/xenbus.h+2−1
@@ -42,6 +42,7 @@ · 41 unmodified lines
4242 #include <linux/completion.h>
4343 #include <linux/init.h>
4444 #include <linux/slab.h>
45+#include <linux/semaphore.h>
4546 #include <xen/interface/xen.h>
4647 #include <xen/interface/grant_table.h>
4748 #include <xen/interface/io/xenbus.h>
@@ -76,7 +77,7 @@ struct xenbus_device { · 28 unmodified lines
7677 enum xenbus_state state;
7778 struct completion down;
7879 struct work_struct work;
79− spinlock_t reclaim_lock;
80+ struct semaphore reclaim_sem;
8081 };
8182
8283 static inline struct xenbus_device *to_xenbus_device(struct device *dev)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t