aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vhost/scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vhost/scsi.c')
-rw-r--r--drivers/vhost/scsi.c52
1 files changed, 35 insertions, 17 deletions
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 4b79a1f2f901..e663921eebb6 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);
@@ -728,7 +728,12 @@ vhost_scsi_get_tag(struct vhost_virtqueue *vq,
728 } 728 }
729 se_sess = tv_nexus->tvn_se_sess; 729 se_sess = tv_nexus->tvn_se_sess;
730 730
731 tag = percpu_ida_alloc(&se_sess->sess_tag_pool, GFP_KERNEL); 731 tag = percpu_ida_alloc(&se_sess->sess_tag_pool, GFP_ATOMIC);
732 if (tag < 0) {
733 pr_err("Unable to obtain tag for tcm_vhost_cmd\n");
734 return ERR_PTR(-ENOMEM);
735 }
736
732 cmd = &((struct tcm_vhost_cmd *)se_sess->sess_cmd_map)[tag]; 737 cmd = &((struct tcm_vhost_cmd *)se_sess->sess_cmd_map)[tag];
733 sg = cmd->tvc_sgl; 738 sg = cmd->tvc_sgl;
734 pages = cmd->tvc_upages; 739 pages = cmd->tvc_upages;
@@ -1051,7 +1056,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
1051 if (data_direction != DMA_NONE) { 1056 if (data_direction != DMA_NONE) {
1052 ret = vhost_scsi_map_iov_to_sgl(cmd, 1057 ret = vhost_scsi_map_iov_to_sgl(cmd,
1053 &vq->iov[data_first], data_num, 1058 &vq->iov[data_first], data_num,
1054 data_direction == DMA_TO_DEVICE); 1059 data_direction == DMA_FROM_DEVICE);
1055 if (unlikely(ret)) { 1060 if (unlikely(ret)) {
1056 vq_err(vq, "Failed to map iov to sgl\n"); 1061 vq_err(vq, "Failed to map iov to sgl\n");
1057 goto err_free; 1062 goto err_free;
@@ -1373,21 +1378,30 @@ static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
1373 return 0; 1378 return 0;
1374} 1379}
1375 1380
1381static void vhost_scsi_free(struct vhost_scsi *vs)
1382{
1383 if (is_vmalloc_addr(vs))
1384 vfree(vs);
1385 else
1386 kfree(vs);
1387}
1388
1376static int vhost_scsi_open(struct inode *inode, struct file *f) 1389static int vhost_scsi_open(struct inode *inode, struct file *f)
1377{ 1390{
1378 struct vhost_scsi *vs; 1391 struct vhost_scsi *vs;
1379 struct vhost_virtqueue **vqs; 1392 struct vhost_virtqueue **vqs;
1380 int r, i; 1393 int r = -ENOMEM, i;
1381 1394
1382 vs = kzalloc(sizeof(*vs), GFP_KERNEL); 1395 vs = kzalloc(sizeof(*vs), GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
1383 if (!vs) 1396 if (!vs) {
1384 return -ENOMEM; 1397 vs = vzalloc(sizeof(*vs));
1398 if (!vs)
1399 goto err_vs;
1400 }
1385 1401
1386 vqs = kmalloc(VHOST_SCSI_MAX_VQ * sizeof(*vqs), GFP_KERNEL); 1402 vqs = kmalloc(VHOST_SCSI_MAX_VQ * sizeof(*vqs), GFP_KERNEL);
1387 if (!vqs) { 1403 if (!vqs)
1388 kfree(vs); 1404 goto err_vqs;
1389 return -ENOMEM;
1390 }
1391 1405
1392 vhost_work_init(&vs->vs_completion_work, vhost_scsi_complete_cmd_work); 1406 vhost_work_init(&vs->vs_completion_work, vhost_scsi_complete_cmd_work);
1393 vhost_work_init(&vs->vs_event_work, tcm_vhost_evt_work); 1407 vhost_work_init(&vs->vs_event_work, tcm_vhost_evt_work);
@@ -1407,14 +1421,18 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
1407 1421
1408 tcm_vhost_init_inflight(vs, NULL); 1422 tcm_vhost_init_inflight(vs, NULL);
1409 1423
1410 if (r < 0) { 1424 if (r < 0)
1411 kfree(vqs); 1425 goto err_init;
1412 kfree(vs);
1413 return r;
1414 }
1415 1426
1416 f->private_data = vs; 1427 f->private_data = vs;
1417 return 0; 1428 return 0;
1429
1430err_init:
1431 kfree(vqs);
1432err_vqs:
1433 vhost_scsi_free(vs);
1434err_vs:
1435 return r;
1418} 1436}
1419 1437
1420static int vhost_scsi_release(struct inode *inode, struct file *f) 1438static int vhost_scsi_release(struct inode *inode, struct file *f)
@@ -1431,7 +1449,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. */ 1449 /* Jobs can re-queue themselves in evt kick handler. Do extra flush. */
1432 vhost_scsi_flush(vs); 1450 vhost_scsi_flush(vs);
1433 kfree(vs->dev.vqs); 1451 kfree(vs->dev.vqs);
1434 kfree(vs); 1452 vhost_scsi_free(vs);
1435 return 0; 1453 return 0;
1436} 1454}
1437 1455