diff mbox series

qdl: Rework qdl_write to limit write sizes to out_maxpktsize

Message ID 20190430235556.2502-1-john.stultz@linaro.org
State New
Headers show
Series qdl: Rework qdl_write to limit write sizes to out_maxpktsize | expand

Commit Message

John Stultz April 30, 2019, 11:55 p.m. UTC
On a number of machines, qdl could cause crashes on the host
system it ran on, due to swiotlb exaustion.

This seems to be due to 1M buffers being used during the writes.

In order to avoid this, rework qdl_write to break up the writes
into out_maxpktsize chunks, and set max_payload_size to 64k

With this patch, I no longer see host crashes when running qdl

Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Amit Pundir <amit.pundir@linaro.org>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: dragonboard-aosp@lists.96boards.org
Signed-off-by: John Stultz <john.stultz@linaro.org>

---
 firehose.c |  2 +-
 qdl.c      | 49 +++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 40 insertions(+), 11 deletions(-)

-- 
2.17.1
diff mbox series

Patch

diff --git a/firehose.c b/firehose.c
index ebe9c52..76dfb96 100644
--- a/firehose.c
+++ b/firehose.c
@@ -198,7 +198,7 @@  static int firehose_nop_parser(xmlNode *node)
 	return !!xmlStrcmp(value, (xmlChar*)"ACK");
 }
 
-static size_t max_payload_size = 1048576;
+static size_t max_payload_size = 65536;
 
 /**
  * firehose_configure_response_parser() - parse a configure response
diff --git a/qdl.c b/qdl.c
index 2b523d2..47debd9 100644
--- a/qdl.c
+++ b/qdl.c
@@ -354,20 +354,49 @@  int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout
 
 int qdl_write(struct qdl_device *qdl, const void *buf, size_t len, bool eot)
 {
+
+	unsigned char *data = (unsigned char*) buf;
 	struct usbdevfs_bulktransfer bulk = {};
-	int ret;
+	unsigned count = 0;
+	size_t len_orig = len;
 	int n;
 
-	bulk.ep = qdl->out_ep;
-	bulk.len = len;
-	bulk.data = (void *)buf;
-	bulk.timeout = 10000;
+	if(len == 0) {
+		bulk.ep = qdl->out_ep;
+		bulk.len = 0;
+		bulk.data = data;
+		bulk.timeout = 1000;
 
-	ret = ioctl(qdl->fd, USBDEVFS_BULK, &bulk);
-	if (ret < 0)
-		return ret;
+		n = ioctl(qdl->fd, USBDEVFS_BULK, &bulk);
+		if(n != 0) {
+			fprintf(stderr,"ERROR: n = %d, errno = %d (%s)\n",
+				n, errno, strerror(errno));
+			return -1;
+		}
+		return 0;
+	}
+
+	while(len > 0) {
+		int xfer;
+		xfer = (len > qdl->out_maxpktsize) ? qdl->out_maxpktsize : len;
+
+		bulk.ep = qdl->out_ep;
+		bulk.len = xfer;
+		bulk.data = data;
+		bulk.timeout = 1000;
+
+		n = ioctl(qdl->fd, USBDEVFS_BULK, &bulk);
+		if(n != xfer) {
+			fprintf(stderr, "ERROR: n = %d, errno = %d (%s)\n",
+				n, errno, strerror(errno));
+			return -1;
+		}
+		count += xfer;
+		len -= xfer;
+		data += xfer;
+	}
 
-	if (eot && (len % qdl->out_maxpktsize) == 0) {
+	if (eot && (len_orig % qdl->out_maxpktsize) == 0) {
 		bulk.ep = qdl->out_ep;
 		bulk.len = 0;
 		bulk.data = NULL;
@@ -378,7 +407,7 @@  int qdl_write(struct qdl_device *qdl, const void *buf, size_t len, bool eot)
 			return n;
 	}
 
-	return ret;
+	return count;
 }
 
 static void print_usage(void)