]>
Commit | Line | Data |
---|---|---|
67b58a20 DM |
1 | vhost-net: extend device allocation to vmalloc |
2 | ||
3 | Backport upstream commit 23cc5a991c7a9fb7e6d6550e65cee4f4173111c5 to | |
4 | 3.10 kernel. | |
5 | In upstream, this code is modified later in patch | |
6 | d04257b07f2362d4eb550952d5bf5f4241a8046d, but it's unapplicable in 3.10 | |
7 | because there's still no open-coded kvfree() function (appeared in | |
8 | v3.15-rc5). | |
9 | ||
10 | Should fix bug reported in forum | |
11 | http://forum.proxmox.com/threads/19194-VM-start-problem-with-virtio-net | |
12 | ||
13 | diff -r -U 3 -p a/drivers/vhost/net.c b/drivers/vhost/net.c | |
14 | --- a/drivers/vhost/net.c 2014-07-16 22:25:31.000000000 +0400 | |
15 | +++ b/drivers/vhost/net.c 2014-09-04 13:56:20.101952635 +0400 | |
16 | @@ -18,6 +18,7 @@ | |
17 | #include <linux/rcupdate.h> | |
18 | #include <linux/file.h> | |
19 | #include <linux/slab.h> | |
20 | +#include <linux/vmalloc.h> | |
21 | ||
22 | #include <linux/net.h> | |
23 | #include <linux/if_packet.h> | |
24 | @@ -706,18 +707,30 @@ static void handle_rx_net(struct vhost_w | |
25 | handle_rx(net); | |
26 | } | |
27 | ||
28 | +static void vhost_net_free(void *addr) | |
29 | +{ | |
30 | + if (is_vmalloc_addr(addr)) | |
31 | + vfree(addr); | |
32 | + else | |
33 | + kfree(addr); | |
34 | +} | |
35 | + | |
36 | static int vhost_net_open(struct inode *inode, struct file *f) | |
37 | { | |
38 | - struct vhost_net *n = kmalloc(sizeof *n, GFP_KERNEL); | |
39 | + struct vhost_net *n; | |
40 | struct vhost_dev *dev; | |
41 | struct vhost_virtqueue **vqs; | |
42 | int r, i; | |
43 | ||
44 | - if (!n) | |
45 | - return -ENOMEM; | |
46 | + n = kmalloc(sizeof *n, GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); | |
47 | + if (!n) { | |
48 | + n = vmalloc(sizeof *n); | |
49 | + if (!n) | |
50 | + return -ENOMEM; | |
51 | + } | |
52 | vqs = kmalloc(VHOST_NET_VQ_MAX * sizeof(*vqs), GFP_KERNEL); | |
53 | if (!vqs) { | |
54 | - kfree(n); | |
55 | + vhost_net_free(n); | |
56 | return -ENOMEM; | |
57 | } | |
58 | ||
59 | @@ -736,7 +749,7 @@ static int vhost_net_open(struct inode * | |
60 | } | |
61 | r = vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX); | |
62 | if (r < 0) { | |
63 | - kfree(n); | |
64 | + vhost_net_free(n); | |
65 | kfree(vqs); | |
66 | return r; | |
67 | } | |
68 | @@ -841,7 +854,7 @@ static int vhost_net_release(struct inod | |
69 | * since jobs can re-queue themselves. */ | |
70 | vhost_net_flush(n); | |
71 | kfree(n->dev.vqs); | |
72 | - kfree(n); | |
73 | + vhost_net_free(n); | |
74 | return 0; | |
75 | } | |
76 |