aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/vhost/scsi.c43
-rw-r--r--drivers/vhost/vhost.c4
2 files changed, 31 insertions, 16 deletions
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 4b79a1f2f901..592b31698fc8 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -461,7 +461,7 @@ static void tcm_vhost_release_cmd(struct se_cmd *se_cmd)
461 u32 i; 461 u32 i;
462 for (i = 0; i < tv_cmd->tvc_sgl_count; i++) 462 for (i = 0; i < tv_cmd->tvc_sgl_count; i++)
463 put_page(sg_page(&tv_cmd->tvc_sgl[i])); 463 put_page(sg_page(&tv_cmd->tvc_sgl[i]));
464 } 464 }
465 465
466 tcm_vhost_put_inflight(tv_cmd->inflight); 466 tcm_vhost_put_inflight(tv_cmd->inflight);
467 percpu_ida_free(&se_sess->sess_tag_pool, se_cmd->map_tag); 467 percpu_ida_free(&se_sess->sess_tag_pool, se_cmd->map_tag);
@@ -1373,21 +1373,30 @@ static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
1373 return 0; 1373 return 0;
1374} 1374}
1375 1375
1376static void vhost_scsi_free(struct vhost_scsi *vs)
1377{
1378 if (is_vmalloc_addr(vs))
1379 vfree(vs);
1380 else
1381 kfree(vs);
1382}
1383
1376static int vhost_scsi_open(struct inode *inode, struct file *f) 1384static int vhost_scsi_open(struct inode *inode, struct file *f)
1377{ 1385{
1378 struct vhost_scsi *vs; 1386 struct vhost_scsi *vs;
1379 struct vhost_virtqueue **vqs; 1387 struct vhost_virtqueue **vqs;
1380 int r, i; 1388 int r = -ENOMEM, i;
1381 1389
1382 vs = kzalloc(sizeof(*vs), GFP_KERNEL); 1390 vs = kzalloc(sizeof(*vs), GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
1383 if (!vs) 1391 if (!vs) {
1384 return -ENOMEM; 1392 vs = vzalloc(sizeof(*vs));
1393 if (!vs)
1394 goto err_vs;
1395 }
1385 1396
1386 vqs = kmalloc(VHOST_SCSI_MAX_VQ * sizeof(*vqs), GFP_KERNEL); 1397 vqs = kmalloc(VHOST_SCSI_MAX_VQ * sizeof(*vqs), GFP_KERNEL);
1387 if (!vqs) { 1398 if (!vqs)
1388 kfree(vs); 1399 goto err_vqs;
1389 return -ENOMEM;
1390 }
1391 1400
1392 vhost_work_init(&vs->vs_completion_work, vhost_scsi_complete_cmd_work); 1401 vhost_work_init(&vs->vs_completion_work, vhost_scsi_complete_cmd_work);
1393 vhost_work_init(&vs->vs_event_work, tcm_vhost_evt_work); 1402 vhost_work_init(&vs->vs_event_work, tcm_vhost_evt_work);
@@ -1407,14 +1416,18 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
1407 1416
1408 tcm_vhost_init_inflight(vs, NULL); 1417 tcm_vhost_init_inflight(vs, NULL);
1409 1418
1410 if (r < 0) { 1419 if (r < 0)
1411 kfree(vqs); 1420 goto err_init;
1412 kfree(vs);
1413 return r;
1414 }
1415 1421
1416 f->private_data = vs; 1422 f->private_data = vs;
1417 return 0; 1423 return 0;
1424
1425err_init:
1426 kfree(vqs);
1427err_vqs:
1428 vhost_scsi_free(vs);
1429err_vs:
1430 return r;
1418} 1431}
1419 1432
1420static int vhost_scsi_release(struct inode *inode, struct file *f) 1433static int vhost_scsi_release(struct inode *inode, struct file *f)
@@ -1431,7 +1444,7 @@ static int vhost_scsi_release(struct inode *inode, struct file *f)
1431 /* Jobs can re-queue themselves in evt kick handler. Do extra flush. */ 1444 /* Jobs can re-queue themselves in evt kick handler. Do extra flush. */
1432 vhost_scsi_flush(vs); 1445 vhost_scsi_flush(vs);
1433 kfree(vs->dev.vqs); 1446 kfree(vs->dev.vqs);
1434 kfree(vs); 1447 vhost_scsi_free(vs);
1435 return 0; 1448 return 0;
1436} 1449}
1437 1450
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 9a9502a4aa50..69068e0d8f31 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -161,9 +161,11 @@ void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work)
161 if (list_empty(&work->node)) { 161 if (list_empty(&work->node)) {
162 list_add_tail(&work->node, &dev->work_list); 162 list_add_tail(&work->node, &dev->work_list);
163 work->queue_seq++; 163 work->queue_seq++;
164 spin_unlock_irqrestore(&dev->work_lock, flags);
164 wake_up_process(dev->worker); 165 wake_up_process(dev->worker);
166 } else {
167 spin_unlock_irqrestore(&dev->work_lock, flags);
165 } 168 }
166 spin_unlock_irqrestore(&dev->work_lock, flags);
167} 169}
168EXPORT_SYMBOL_GPL(vhost_work_queue); 170EXPORT_SYMBOL_GPL(vhost_work_queue);
169 171