diff options
Diffstat (limited to 'drivers/vhost/tcm_vhost.c')
| -rw-r--r-- | drivers/vhost/tcm_vhost.c | 26 | 
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c index 9951297b242..2968b493465 100644 --- a/drivers/vhost/tcm_vhost.c +++ b/drivers/vhost/tcm_vhost.c @@ -60,6 +60,15 @@ enum {  	VHOST_SCSI_VQ_IO = 2,  }; +/* + * VIRTIO_RING_F_EVENT_IDX seems broken. Not sure the bug is in + * kernel but disabling it helps. + * TODO: debug and remove the workaround. + */ +enum { +	VHOST_SCSI_FEATURES = VHOST_FEATURES & (~VIRTIO_RING_F_EVENT_IDX) +}; +  #define VHOST_SCSI_MAX_TARGET	256  #define VHOST_SCSI_MAX_VQ	128 @@ -850,7 +859,7 @@ static int vhost_scsi_clear_endpoint(  	for (index = 0; index < vs->dev.nvqs; ++index) {  		if (!vhost_vq_access_ok(&vs->vqs[index])) {  			ret = -EFAULT; -			goto err; +			goto err_dev;  		}  	}  	for (i = 0; i < VHOST_SCSI_MAX_TARGET; i++) { @@ -860,10 +869,11 @@ static int vhost_scsi_clear_endpoint(  		if (!tv_tpg)  			continue; +		mutex_lock(&tv_tpg->tv_tpg_mutex);  		tv_tport = tv_tpg->tport;  		if (!tv_tport) {  			ret = -ENODEV; -			goto err; +			goto err_tpg;  		}  		if (strcmp(tv_tport->tport_name, t->vhost_wwpn)) { @@ -872,16 +882,19 @@ static int vhost_scsi_clear_endpoint(  				tv_tport->tport_name, tv_tpg->tport_tpgt,  				t->vhost_wwpn, t->vhost_tpgt);  			ret = -EINVAL; -			goto err; +			goto err_tpg;  		}  		tv_tpg->tv_tpg_vhost_count--;  		vs->vs_tpg[target] = NULL;  		vs->vs_endpoint = false; +		mutex_unlock(&tv_tpg->tv_tpg_mutex);  	}  	mutex_unlock(&vs->dev.mutex);  	return 0; -err: +err_tpg: +	mutex_unlock(&tv_tpg->tv_tpg_mutex); +err_dev:  	mutex_unlock(&vs->dev.mutex);  	return ret;  } @@ -937,11 +950,12 @@ static void vhost_scsi_flush(struct vhost_scsi *vs)  	for (i = 0; i < VHOST_SCSI_MAX_VQ; i++)  		vhost_scsi_flush_vq(vs, i); +	vhost_work_flush(&vs->dev, &vs->vs_completion_work);  }  static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)  { -	if (features & ~VHOST_FEATURES) +	if (features & ~VHOST_SCSI_FEATURES)  		return -EOPNOTSUPP;  	mutex_lock(&vs->dev.mutex); @@ -987,7 +1001,7 @@ static long vhost_scsi_ioctl(struct file *f, unsigned int ioctl,  			return -EFAULT;  		return 0;  	case VHOST_GET_FEATURES: -		features = VHOST_FEATURES; +		features = VHOST_SCSI_FEATURES;  		if (copy_to_user(featurep, &features, sizeof features))  			return -EFAULT;  		return 0;  |