Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4410bacb authored by Pratham Pratap's avatar Pratham Pratap
Browse files

USB: f_mtp: Improve MTP write throughput



Commit fc71db86987e8 ("USB: f_mtp: Perform vfs_write under mutex
protection) introduces mutex protection to avoid request buffer
freed while vfs_write or copy_to_user happens. This introduced
significant amount of delay for mtp_write throughput. Fix
this by reverting the patch.

Change-Id: I97e513a175b2a6691f42f8e762e2f8fd9bdf35f1
Signed-off-by: default avatarPratham Pratap <prathampratap@codeaurora.org>
parent 06c68199
Loading
Loading
Loading
Loading
+0 −36
Original line number Diff line number Diff line
@@ -150,7 +150,6 @@ struct mtp_dev {
	} perf[MAX_ITERATION];
	unsigned int dbg_read_index;
	unsigned int dbg_write_index;
	struct mutex  read_mutex;
};

static void *_mtp_ipc_log;
@@ -650,18 +649,11 @@ static ssize_t mtp_read(struct file *fp, char __user *buf,
	dev->state = STATE_BUSY;
	spin_unlock_irq(&dev->lock);

	mutex_lock(&dev->read_mutex);
	if (dev->state == STATE_OFFLINE) {
		r = -EIO;
		mutex_unlock(&dev->read_mutex);
		goto done;
	}
requeue_req:
	/* queue a request */
	req = dev->rx_req[0];
	req->length = len;
	dev->rx_done = 0;
	mutex_unlock(&dev->read_mutex);
	ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL);
	if (ret < 0) {
		r = -EIO;
@@ -687,7 +679,6 @@ static ssize_t mtp_read(struct file *fp, char __user *buf,
		usb_ep_dequeue(dev->ep_out, req);
		goto done;
	}
	mutex_lock(&dev->read_mutex);
	if (dev->state == STATE_BUSY) {
		/* If we got a 0-len packet, throw it back and try again. */
		if (req->actual == 0)
@@ -701,7 +692,6 @@ static ssize_t mtp_read(struct file *fp, char __user *buf,
	} else
		r = -EIO;

	mutex_unlock(&dev->read_mutex);
done:
	spin_lock_irq(&dev->lock);
	if (dev->state == STATE_CANCELED)
@@ -949,12 +939,6 @@ static void receive_file_work(struct work_struct *data)

	while (count > 0 || write_req) {
		if (count > 0) {
			mutex_lock(&dev->read_mutex);
			if (dev->state == STATE_OFFLINE) {
				r = -EIO;
				mutex_unlock(&dev->read_mutex);
				break;
			}
			/* queue a request */
			read_req = dev->rx_req[cur_buf];
			cur_buf = (cur_buf + 1) % RX_REQ_MAX;
@@ -963,7 +947,6 @@ static void receive_file_work(struct work_struct *data)
			read_req->length = mtp_rx_req_len;

			dev->rx_done = 0;
			mutex_unlock(&dev->read_mutex);
			ret = usb_ep_queue(dev->ep_out, read_req, GFP_KERNEL);
			if (ret < 0) {
				r = -EIO;
@@ -976,25 +959,17 @@ static void receive_file_work(struct work_struct *data)
		if (write_req) {
			mtp_log("rx %pK %d\n", write_req, write_req->actual);
			start_time = ktime_get();
			mutex_lock(&dev->read_mutex);
			if (dev->state == STATE_OFFLINE) {
				r = -EIO;
				mutex_unlock(&dev->read_mutex);
				break;
			}
			ret = vfs_write(filp, write_req->buf, write_req->actual,
				&offset);
			mtp_log("vfs_write %d\n", ret);
			if (ret != write_req->actual) {
				r = -EIO;
				mutex_unlock(&dev->read_mutex);
				if (dev->state != STATE_OFFLINE)
					dev->state = STATE_ERROR;
				if (read_req && !dev->rx_done)
					usb_ep_dequeue(dev->ep_out, read_req);
				break;
			}
			mutex_unlock(&dev->read_mutex);
			dev->perf[dev->dbg_write_index].vfs_wtime =
				ktime_to_us(ktime_sub(ktime_get(), start_time));
			dev->perf[dev->dbg_write_index].vfs_wbytes = ret;
@@ -1022,12 +997,6 @@ static void receive_file_work(struct work_struct *data)
				break;
			}

			mutex_lock(&dev->read_mutex);
			if (dev->state == STATE_OFFLINE) {
				r = -EIO;
				mutex_unlock(&dev->read_mutex);
				break;
			}
			/* Check if we aligned the size due to MTU constraint */
			if (count < read_req->length)
				read_req->actual = (read_req->actual > count ?
@@ -1048,7 +1017,6 @@ static void receive_file_work(struct work_struct *data)

			write_req = read_req;
			read_req = NULL;
			mutex_unlock(&dev->read_mutex);
		}
	}

@@ -1501,14 +1469,12 @@ mtp_function_unbind(struct usb_configuration *c, struct usb_function *f)
	fi_mtp = container_of(f->fi, struct mtp_instance, func_inst);
	mtp_string_defs[INTERFACE_STRING_INDEX].id = 0;
	mtp_log("dev: %pK\n", dev);
	mutex_lock(&dev->read_mutex);
	while ((req = mtp_req_get(dev, &dev->tx_idle)))
		mtp_request_free(req, dev->ep_in);
	for (i = 0; i < RX_REQ_MAX; i++)
		mtp_request_free(dev->rx_req[i], dev->ep_out);
	while ((req = mtp_req_get(dev, &dev->intr_idle)))
		mtp_request_free(req, dev->ep_intr);
	mutex_unlock(&dev->read_mutex);
	spin_lock_irq(&dev->lock);
	dev->state = STATE_OFFLINE;
	dev->cdev = NULL;
@@ -1853,8 +1819,6 @@ struct usb_function_instance *alloc_inst_mtp_ptp(bool mtp_config)
	usb_os_desc_prepare_interf_dir(&fi_mtp->func_inst.group, 1,
					descs, names, THIS_MODULE);

	mutex_init(&fi_mtp->dev->read_mutex);

	return  &fi_mtp->func_inst;
}
EXPORT_SYMBOL_GPL(alloc_inst_mtp_ptp);