Skip to content

Commit cbee7c8

Browse files
committed
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
2 parents fa883d6 + 4ab50af commit cbee7c8

File tree

8 files changed

+64
-51
lines changed

8 files changed

+64
-51
lines changed

drivers/block/xen-blkfront.c

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ struct blkfront_info
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);
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,
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,16 +1193,15 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
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;
11871200

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 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo)
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)
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,
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,
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 @@ static int talk_to_blkback(struct xenbus_device *dev,
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 @@ static int talk_to_blkback(struct xenbus_device *dev,
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 @@ static int talk_to_blkback(struct xenbus_device *dev,
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)
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)
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,16 +2024,15 @@ static int blkif_recover(struct blkfront_info *info)
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(). */
20232031
blkif_set_queue_limits(info);
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)
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)
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)
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)
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)
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)
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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ struct xen_pcibk_dev_data {
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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,8 @@ static int process_msg(void)
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)
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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,9 @@ int xenbus_dev_probe(struct device *_dev)
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)
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,
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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
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)
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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,11 @@ static bool xenbus_ok(void)
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)
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)
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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ struct vtpm_shared_page {
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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
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 {
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)

0 commit comments

Comments
 (0)