Commit b1ad8496c9f47d8b545ed4e948ab4271627c8bcf
Committed by
Michael S. Tsirkin
1 parent
54db63c2ca
Exists in
master
and in
20 other branches
vhost-net: Free ubuf when vhost_dev_set_owner fails
Signed-off-by: Asias He <asias@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Showing 1 changed file with 32 additions and 6 deletions Side-by-side Diff
drivers/vhost/net.c
... | ... | @@ -146,6 +146,19 @@ |
146 | 146 | kfree(ubufs); |
147 | 147 | } |
148 | 148 | |
149 | +static void vhost_net_clear_ubuf_info(struct vhost_net *n) | |
150 | +{ | |
151 | + | |
152 | + bool zcopy; | |
153 | + int i; | |
154 | + | |
155 | + for (i = 0; i < n->dev.nvqs; ++i) { | |
156 | + zcopy = vhost_zcopy_mask & (0x1 << i); | |
157 | + if (zcopy) | |
158 | + kfree(n->vqs[i].ubuf_info); | |
159 | + } | |
160 | +} | |
161 | + | |
149 | 162 | int vhost_net_set_ubuf_info(struct vhost_net *n) |
150 | 163 | { |
151 | 164 | bool zcopy; |
... | ... | @@ -1027,6 +1040,23 @@ |
1027 | 1040 | return 0; |
1028 | 1041 | } |
1029 | 1042 | |
1043 | +static long vhost_net_set_owner(struct vhost_net *n) | |
1044 | +{ | |
1045 | + int r; | |
1046 | + | |
1047 | + mutex_lock(&n->dev.mutex); | |
1048 | + r = vhost_net_set_ubuf_info(n); | |
1049 | + if (r) | |
1050 | + goto out; | |
1051 | + r = vhost_dev_set_owner(&n->dev); | |
1052 | + if (r) | |
1053 | + vhost_net_clear_ubuf_info(n); | |
1054 | + vhost_net_flush(n); | |
1055 | +out: | |
1056 | + mutex_unlock(&n->dev.mutex); | |
1057 | + return r; | |
1058 | +} | |
1059 | + | |
1030 | 1060 | static long vhost_net_ioctl(struct file *f, unsigned int ioctl, |
1031 | 1061 | unsigned long arg) |
1032 | 1062 | { |
1033 | 1063 | |
1034 | 1064 | |
... | ... | @@ -1055,19 +1085,15 @@ |
1055 | 1085 | return vhost_net_set_features(n, features); |
1056 | 1086 | case VHOST_RESET_OWNER: |
1057 | 1087 | return vhost_net_reset_owner(n); |
1088 | + case VHOST_SET_OWNER: | |
1089 | + return vhost_net_set_owner(n); | |
1058 | 1090 | default: |
1059 | 1091 | mutex_lock(&n->dev.mutex); |
1060 | - if (ioctl == VHOST_SET_OWNER) { | |
1061 | - r = vhost_net_set_ubuf_info(n); | |
1062 | - if (r) | |
1063 | - goto out; | |
1064 | - } | |
1065 | 1092 | r = vhost_dev_ioctl(&n->dev, ioctl, argp); |
1066 | 1093 | if (r == -ENOIOCTLCMD) |
1067 | 1094 | r = vhost_vring_ioctl(&n->dev, ioctl, argp); |
1068 | 1095 | else |
1069 | 1096 | vhost_net_flush(n); |
1070 | -out: | |
1071 | 1097 | mutex_unlock(&n->dev.mutex); |
1072 | 1098 | return r; |
1073 | 1099 | } |