Skip to content

Commit a144ff0

Browse files
Ian CampbellJens Axboe
authored andcommitted
xen: Avoid allocations causing swap activity on the resume path
Avoid allocations causing swap activity on the resume path by preventing the allocations from doing IO and allowing them to access the emergency pools. These paths are used when a frontend device is trying to connect to its backend driver over Xenbus. These reconnections are triggered on demand by IO, so by definition there is already IO underway, and further IO would naturally deadlock. On resume, this path is triggered when the running system tries to continue using its devices. If it cannot then the resume will fail; to try to avoid this we let it dip into the emergency pools. [ linux-2.6.18-xen changesets e8b49cfbdac, fdb998e79aba ] Signed-off-by: Ian Campbell <[email protected]> Signed-off-by: Jeremy Fitzhardinge <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 5a60d0c commit a144ff0

File tree

4 files changed

+11
-10
lines changed

4 files changed

+11
-10
lines changed

drivers/block/xen-blkfront.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ static int setup_blkring(struct xenbus_device *dev,
584584

585585
info->ring_ref = GRANT_INVALID_REF;
586586

587-
sring = (struct blkif_sring *)__get_free_page(GFP_KERNEL);
587+
sring = (struct blkif_sring *)__get_free_page(GFP_NOIO | __GFP_HIGH);
588588
if (!sring) {
589589
xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
590590
return -ENOMEM;
@@ -741,7 +741,8 @@ static int blkif_recover(struct blkfront_info *info)
741741
int j;
742742

743743
/* Stage 1: Make a safe copy of the shadow state. */
744-
copy = kmalloc(sizeof(info->shadow), GFP_KERNEL);
744+
copy = kmalloc(sizeof(info->shadow),
745+
GFP_NOIO | __GFP_REPEAT | __GFP_HIGH);
745746
if (!copy)
746747
return -ENOMEM;
747748
memcpy(copy, info->shadow, sizeof(info->shadow));

drivers/net/xen-netfront.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,7 @@ static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info)
13241324
goto fail;
13251325
}
13261326

1327-
txs = (struct xen_netif_tx_sring *)get_zeroed_page(GFP_KERNEL);
1327+
txs = (struct xen_netif_tx_sring *)get_zeroed_page(GFP_NOIO | __GFP_HIGH);
13281328
if (!txs) {
13291329
err = -ENOMEM;
13301330
xenbus_dev_fatal(dev, err, "allocating tx ring page");
@@ -1340,7 +1340,7 @@ static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info)
13401340
}
13411341

13421342
info->tx_ring_ref = err;
1343-
rxs = (struct xen_netif_rx_sring *)get_zeroed_page(GFP_KERNEL);
1343+
rxs = (struct xen_netif_rx_sring *)get_zeroed_page(GFP_NOIO | __GFP_HIGH);
13441344
if (!rxs) {
13451345
err = -ENOMEM;
13461346
xenbus_dev_fatal(dev, err, "allocating rx ring page");

drivers/xen/xenbus/xenbus_client.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ int xenbus_watch_pathfmt(struct xenbus_device *dev,
117117
char *path;
118118

119119
va_start(ap, pathfmt);
120-
path = kvasprintf(GFP_KERNEL, pathfmt, ap);
120+
path = kvasprintf(GFP_NOIO | __GFP_HIGH, pathfmt, ap);
121121
va_end(ap);
122122

123123
if (!path) {

drivers/xen/xenbus/xenbus_xs.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,9 @@ static char *join(const char *dir, const char *name)
283283
char *buffer;
284284

285285
if (strlen(name) == 0)
286-
buffer = kasprintf(GFP_KERNEL, "%s", dir);
286+
buffer = kasprintf(GFP_NOIO | __GFP_HIGH, "%s", dir);
287287
else
288-
buffer = kasprintf(GFP_KERNEL, "%s/%s", dir, name);
288+
buffer = kasprintf(GFP_NOIO | __GFP_HIGH, "%s/%s", dir, name);
289289
return (!buffer) ? ERR_PTR(-ENOMEM) : buffer;
290290
}
291291

@@ -297,7 +297,7 @@ static char **split(char *strings, unsigned int len, unsigned int *num)
297297
*num = count_strings(strings, len);
298298

299299
/* Transfer to one big alloc for easy freeing. */
300-
ret = kmalloc(*num * sizeof(char *) + len, GFP_KERNEL);
300+
ret = kmalloc(*num * sizeof(char *) + len, GFP_NOIO | __GFP_HIGH);
301301
if (!ret) {
302302
kfree(strings);
303303
return ERR_PTR(-ENOMEM);
@@ -751,7 +751,7 @@ static int process_msg(void)
751751
}
752752

753753

754-
msg = kmalloc(sizeof(*msg), GFP_KERNEL);
754+
msg = kmalloc(sizeof(*msg), GFP_NOIO | __GFP_HIGH);
755755
if (msg == NULL) {
756756
err = -ENOMEM;
757757
goto out;
@@ -763,7 +763,7 @@ static int process_msg(void)
763763
goto out;
764764
}
765765

766-
body = kmalloc(msg->hdr.len + 1, GFP_KERNEL);
766+
body = kmalloc(msg->hdr.len + 1, GFP_NOIO | __GFP_HIGH);
767767
if (body == NULL) {
768768
kfree(msg);
769769
err = -ENOMEM;

0 commit comments

Comments
 (0)