resending patches for chaoskey

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I got more patches to improve throughput
but I cannot test them.

	Regards


From b32c2f840c1ff0d0e93b627eb07b2fdc11f37bb5 Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oneukum@xxxxxxxx>
Date: Thu, 25 Feb 2016 12:20:12 +0100
Subject: [PATCH 1/4] chaoskey: O_NONBLOCK in concurrent reads

This changes the locking in chaoskey_read() to correctly
handle O_NONBLOCK in the case of concurrent readers.

Signed-off-by: Oliver Neukum <oneukum@xxxxxxxx>
---
 drivers/usb/misc/chaoskey.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c
index 76350e4..f7e76a3 100644
--- a/drivers/usb/misc/chaoskey.c
+++ b/drivers/usb/misc/chaoskey.c
@@ -438,9 +438,19 @@ static ssize_t chaoskey_read(struct file *file,
 			goto bail;
 		mutex_unlock(&dev->rng_lock);
 
-		result = mutex_lock_interruptible(&dev->lock);
-		if (result)
-			goto bail;
+		if (file->f_flags & O_NONBLOCK) {
+			result = mutex_trylock(&dev->lock);
+			if (result == 0) {
+				result = -EAGAIN;
+				goto bail;
+			} else {
+				result = 0;
+			}
+		} else {
+			result = mutex_lock_interruptible(&dev->lock);
+			if (result)
+				goto bail;
+		}
 		if (dev->valid == dev->used) {
 			result = _chaoskey_fill(dev);
 			if (result < 0) {
-- 
2.1.4

From 8d6c9c8ce3adf192a2fe19fa247208d91ee5e900 Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oneukum@xxxxxxxx>
Date: Thu, 25 Feb 2016 14:20:22 +0100
Subject: [PATCH 2/4] chaoskey: introduce asynchronous reads

This divides requesting IO and waiting for IO from each other.

Signed-off-by: Oliver Neukum <oneukum@xxxxxxxx>
---
 drivers/usb/misc/chaoskey.c | 37 ++++++++++++++++++++++++++++++-------
 1 file changed, 30 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c
index f7e76a3..f47e5a7 100644
--- a/drivers/usb/misc/chaoskey.c
+++ b/drivers/usb/misc/chaoskey.c
@@ -351,14 +351,12 @@ static void chaos_read_callback(struct urb *urb)
 	wake_up(&dev->wait_q);
 }
 
-/* Fill the buffer. Called with dev->lock held
- */
-static int _chaoskey_fill(struct chaoskey *dev)
+static int chaoskey_request_fill(struct chaoskey *dev)
 {
 	DEFINE_WAIT(wait);
 	int result;
 
-	usb_dbg(dev->interface, "fill");
+	usb_dbg(dev->interface, "request fill");
 
 	/* Return immediately if someone called before the buffer was
 	 * empty */
@@ -389,6 +387,22 @@ static int _chaoskey_fill(struct chaoskey *dev)
 		goto out;
 	}
 
+	/*
+	 * powering down while a read is under way
+	 * is blocked in suspend()
+	 */
+	usb_autopm_put_interface(dev->interface);
+	return 0;
+out:
+	usb_autopm_put_interface(dev->interface);
+	return result;
+}
+
+static int chaoskey_wait_fill(struct chaoskey *dev)
+{
+	DEFINE_WAIT(wait);
+	int result;
+
 	result = wait_event_interruptible_timeout(
 		dev->wait_q,
 		!dev->reading,
@@ -403,7 +417,6 @@ static int _chaoskey_fill(struct chaoskey *dev)
 		result = dev->valid;
 out:
 	/* Let the device go back to sleep eventually */
-	usb_autopm_put_interface(dev->interface);
 
 	usb_dbg(dev->interface, "read %d bytes", dev->valid);
 
@@ -452,7 +465,12 @@ static ssize_t chaoskey_read(struct file *file,
 				goto bail;
 		}
 		if (dev->valid == dev->used) {
-			result = _chaoskey_fill(dev);
+			result = chaoskey_request_fill(dev);
+			if (result < 0) {
+				mutex_unlock(&dev->lock);
+				goto bail;
+			}
+			result = chaoskey_wait_fill(dev);
 			if (result < 0) {
 				mutex_unlock(&dev->lock);
 				goto bail;
@@ -520,7 +538,7 @@ static int chaoskey_rng_read(struct hwrng *rng, void *data,
 	 * the buffer will still be empty
 	 */
 	if (dev->valid == dev->used)
-		(void) _chaoskey_fill(dev);
+		(void) chaoskey_request_fill(dev);
 
 	this_time = dev->valid - dev->used;
 	if (this_time > max)
@@ -540,6 +558,11 @@ static int chaoskey_rng_read(struct hwrng *rng, void *data,
 static int chaoskey_suspend(struct usb_interface *interface,
 			    pm_message_t message)
 {
+	struct chaoskey *dev = usb_get_intfdata(interface);
+
+	if (dev->reading && PMSG_IS_AUTO(message))
+		return -EBUSY;
+
 	usb_dbg(interface, "suspend");
 	return 0;
 }
-- 
2.1.4

From 877a5c63bf1b8b379971016f9537063557dda81a Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oneukum@xxxxxxxx>
Date: Thu, 25 Feb 2016 14:42:04 +0100
Subject: [PATCH 3/4] chaoskey: make read() obey O_NONBLOCK

This skips waiting for a read if O_NONBLOCK is set.

Signed-off-by: Oliver Neukum <oneukum@xxxxxxxx>
---
 drivers/usb/misc/chaoskey.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c
index f47e5a7..19dfbb7 100644
--- a/drivers/usb/misc/chaoskey.c
+++ b/drivers/usb/misc/chaoskey.c
@@ -470,10 +470,14 @@ static ssize_t chaoskey_read(struct file *file,
 				mutex_unlock(&dev->lock);
 				goto bail;
 			}
-			result = chaoskey_wait_fill(dev);
-			if (result < 0) {
-				mutex_unlock(&dev->lock);
-				goto bail;
+			if (!(file->f_flags & O_NONBLOCK)) {
+				result = chaoskey_wait_fill(dev);
+				if (result < 0) {
+					mutex_unlock(&dev->lock);
+					goto bail;
+				}
+			} else {
+				result = -EAGAIN;
 			}
 		}
 
-- 
2.1.4

From 4c27eb2e5cd463176f9c962e05924db83b3a1d3c Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oneukum@xxxxxxxx>
Date: Thu, 25 Feb 2016 20:23:46 +0100
Subject: [PATCH 4/4] chaoskey: request data asynchronously

This requests more data if a read has exhausted the buffer
just to have it ready sooner.

Signed-off-by: Oliver Neukum <oneukum@xxxxxxxx>
---
 drivers/usb/misc/chaoskey.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c
index 19dfbb7..8477587 100644
--- a/drivers/usb/misc/chaoskey.c
+++ b/drivers/usb/misc/chaoskey.c
@@ -372,6 +372,9 @@ static int chaoskey_request_fill(struct chaoskey *dev)
 		return -ENODEV;
 	}
 
+	if (dev->reading)
+		return -EBUSY;
+
 	/* Make sure the device is awake */
 	result = usb_autopm_get_interface(dev->interface);
 	if (result) {
@@ -503,13 +506,16 @@ static ssize_t chaoskey_read(struct file *file,
 		dev->used += this_time;
 		mutex_unlock(&dev->lock);
 	}
+	/* request data on suspicion that it will eventually be used */
+	if (dev->valid == dev->used)
+		(void)chaoskey_request_fill(dev);
 bail:
 	if (read_count) {
 		usb_dbg(dev->interface, "read %zu bytes", read_count);
 		return read_count;
 	}
 	usb_dbg(dev->interface, "empty read, result %d", result);
-	if (result == -ETIMEDOUT)
+	if (result == -ETIMEDOUT || result == -EBUSY)
 		result = -EAGAIN;
 	return result;
 }
-- 
2.1.4


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux