All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] posix clocks: replace mutex with reader/writer semaphore
@ 2011-03-30 13:24 Richard Cochran
  2011-03-30 13:41 ` Thomas Gleixner
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Cochran @ 2011-03-30 13:24 UTC (permalink / raw)
  To: linux-kernel; +Cc: John Stultz, Thomas Gleixner

A dynamic posix clock is protected from asynchronous removal by a mutex.
However, using a mutex has the unwanted effect that a long running clock
operation in one process will unnecessarily block other processes.

For example, one process might call read() to get an external time stamp
coming in at one pulse per second. A second process calling clock_gettime
would have to wait for almost a whole second.

This patch fixes the issue by using a reader/writer semaphore instead of
a mutex.

Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
 include/linux/posix-clock.h |    5 +++--
 kernel/time/posix-clock.c   |   24 +++++++++---------------
 2 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h
index 369e19d..7f1183d 100644
--- a/include/linux/posix-clock.h
+++ b/include/linux/posix-clock.h
@@ -24,6 +24,7 @@
 #include <linux/fs.h>
 #include <linux/poll.h>
 #include <linux/posix-timers.h>
+#include <linux/rwsem.h>
 
 struct posix_clock;
 
@@ -104,7 +105,7 @@ struct posix_clock_operations {
  * @ops:     Functional interface to the clock
  * @cdev:    Character device instance for this clock
  * @kref:    Reference count.
- * @mutex:   Protects the 'zombie' field from concurrent access.
+ * @rwsem:   Protects the 'zombie' field from concurrent access.
  * @zombie:  If 'zombie' is true, then the hardware has disappeared.
  * @release: A function to free the structure when the reference count reaches
  *           zero. May be NULL if structure is statically allocated.
@@ -117,7 +118,7 @@ struct posix_clock {
 	struct posix_clock_operations ops;
 	struct cdev cdev;
 	struct kref kref;
-	struct mutex mutex;
+	struct rw_semaphore rwsem;
 	bool zombie;
 	void (*release)(struct posix_clock *clk);
 };
diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
index 25028dd..c340ca6 100644
--- a/kernel/time/posix-clock.c
+++ b/kernel/time/posix-clock.c
@@ -19,7 +19,6 @@
  */
 #include <linux/device.h>
 #include <linux/file.h>
-#include <linux/mutex.h>
 #include <linux/posix-clock.h>
 #include <linux/slab.h>
 #include <linux/syscalls.h>
@@ -34,19 +33,19 @@ static struct posix_clock *get_posix_clock(struct file *fp)
 {
 	struct posix_clock *clk = fp->private_data;
 
-	mutex_lock(&clk->mutex);
+	down_read(&clk->rwsem);
 
 	if (!clk->zombie)
 		return clk;
 
-	mutex_unlock(&clk->mutex);
+	up_read(&clk->rwsem);
 
 	return NULL;
 }
 
 static void put_posix_clock(struct posix_clock *clk)
 {
-	mutex_unlock(&clk->mutex);
+	up_read(&clk->rwsem);
 }
 
 static ssize_t posix_clock_read(struct file *fp, char __user *buf,
@@ -156,7 +155,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
 	struct posix_clock *clk =
 		container_of(inode->i_cdev, struct posix_clock, cdev);
 
-	mutex_lock(&clk->mutex);
+	down_read(&clk->rwsem);
 
 	if (clk->zombie) {
 		err = -ENODEV;
@@ -172,7 +171,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
 		fp->private_data = clk;
 	}
 out:
-	mutex_unlock(&clk->mutex);
+	up_read(&clk->rwsem);
 	return err;
 }
 
@@ -211,25 +210,20 @@ int posix_clock_register(struct posix_clock *clk, dev_t devid)
 	int err;
 
 	kref_init(&clk->kref);
-	mutex_init(&clk->mutex);
+	init_rwsem(&clk->rwsem);
 
 	cdev_init(&clk->cdev, &posix_clock_file_operations);
 	clk->cdev.owner = clk->ops.owner;
 	err = cdev_add(&clk->cdev, devid, 1);
-	if (err)
-		goto no_cdev;
 
 	return err;
-no_cdev:
-	mutex_destroy(&clk->mutex);
-	return err;
 }
 EXPORT_SYMBOL_GPL(posix_clock_register);
 
 static void delete_clock(struct kref *kref)
 {
 	struct posix_clock *clk = container_of(kref, struct posix_clock, kref);
-	mutex_destroy(&clk->mutex);
+
 	if (clk->release)
 		clk->release(clk);
 }
@@ -238,9 +232,9 @@ void posix_clock_unregister(struct posix_clock *clk)
 {
 	cdev_del(&clk->cdev);
 
-	mutex_lock(&clk->mutex);
+	down_write(&clk->rwsem);
 	clk->zombie = true;
-	mutex_unlock(&clk->mutex);
+	up_write(&clk->rwsem);
 
 	kref_put(&clk->kref, delete_clock);
 }
-- 
1.7.0.4


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] posix clocks: replace mutex with reader/writer semaphore
  2011-03-30 13:24 [PATCH] posix clocks: replace mutex with reader/writer semaphore Richard Cochran
@ 2011-03-30 13:41 ` Thomas Gleixner
  2011-04-14 18:04   ` Richard Cochran
  0 siblings, 1 reply; 3+ messages in thread
From: Thomas Gleixner @ 2011-03-30 13:41 UTC (permalink / raw)
  To: Richard Cochran; +Cc: linux-kernel, John Stultz

On Wed, 30 Mar 2011, Richard Cochran wrote:

> A dynamic posix clock is protected from asynchronous removal by a mutex.
> However, using a mutex has the unwanted effect that a long running clock
> operation in one process will unnecessarily block other processes.
> 
> For example, one process might call read() to get an external time stamp
> coming in at one pulse per second. A second process calling clock_gettime
> would have to wait for almost a whole second.
> 
> This patch fixes the issue by using a reader/writer semaphore instead of
> a mutex.

Yuck. /me wonders why we did not see that during the review :)
 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] posix clocks: replace mutex with reader/writer semaphore
  2011-03-30 13:41 ` Thomas Gleixner
@ 2011-04-14 18:04   ` Richard Cochran
  0 siblings, 0 replies; 3+ messages in thread
From: Richard Cochran @ 2011-04-14 18:04 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: linux-kernel, John Stultz

On Wed, Mar 30, 2011 at 03:41:40PM +0200, Thomas Gleixner wrote:
> On Wed, 30 Mar 2011, Richard Cochran wrote:
> 
> > A dynamic posix clock is protected from asynchronous removal by a mutex.
> > However, using a mutex has the unwanted effect that a long running clock
> > operation in one process will unnecessarily block other processes.
> > 
> > For example, one process might call read() to get an external time stamp
> > coming in at one pulse per second. A second process calling clock_gettime
> > would have to wait for almost a whole second.
> > 
> > This patch fixes the issue by using a reader/writer semaphore instead of
> > a mutex.
> 
> Yuck. /me wonders why we did not see that during the review :)

Thomas,

I don't see this in -rc3, but I think it should go in.
Can you please take this one?

Thanks,

Richard



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-04-14 18:05 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-30 13:24 [PATCH] posix clocks: replace mutex with reader/writer semaphore Richard Cochran
2011-03-30 13:41 ` Thomas Gleixner
2011-04-14 18:04   ` Richard Cochran

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.