From: Magnus Lynch <maglyx@gmail.com>
To: Clemens Ladisch <clemens@ladisch.de>
Cc: "Venkatesh Pallipadi (Venki)" <venkatesh.pallipadi@intel.com>,
"Vojtech Pavlik" <vojtech@suse.cz>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Eric W. Biederman" <ebiederm@xmission.com>,
"Paul Gortmaker" <paul.gortmaker@windriver.com>,
"Suresh Siddha" <suresh.b.siddha@intel.com>,
"Thomas Gleixner" <tglx@linutronix.de>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] hpet: factor timer allocate from open
Date: Sun, 07 Mar 2010 16:04:39 -0800 (PST) [thread overview]
Message-ID: <4b943f17.4902be0a.5bd5.0917@mx.google.com> (raw)
In-Reply-To: <4B8F72B5.3000408@ladisch.de>
Clemens Ladisch wrote:
>> If so I can change that. I did add the explicit form of allocating
>> timers to accomodate such a case hypothetically (open, allocate timer,
>> get info).
>
> This wouldn't be backwards compatible.
OK, here's a version that retains HPET_INFO semantics.
Signed-off-by: Magnus Lynch <maglyx@gmail.com>
---
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index e481c59..97f8d5b 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -244,16 +244,40 @@ static void hpet_timer_set_irq(struct hpet_dev *devp)
static int hpet_open(struct inode *inode, struct file *file)
{
- struct hpet_dev *devp;
struct hpets *hpetp;
- int i;
if (file->f_mode & FMODE_WRITE)
return -EINVAL;
+ hpetp = hpets;
+ /* starting with timer-neutral instance */
+ file->private_data = &hpetp->hp_dev[hpetp->hp_ntimer];
+
+ return 0;
+}
+
+static int hpet_alloc_timer(struct file *file)
+{
+ struct hpet_dev *devp;
+ struct hpets *hpetp;
+ int i;
+
+ /* once acquired, will remain */
+ devp = file->private_data;
+ if (devp->hd_timer)
+ return 0;
+
lock_kernel();
spin_lock_irq(&hpet_lock);
+ /* check for race acquiring */
+ devp = file->private_data;
+ if (devp->hd_timer) {
+ spin_unlock_irq(&hpet_lock);
+ unlock_kernel();
+ return 0;
+ }
+
for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next)
for (i = 0; i < hpetp->hp_ntimer; i++)
if (hpetp->hp_dev[i].hd_flags & HPET_OPEN)
@@ -384,6 +408,10 @@ static int hpet_fasync(int fd, struct file *file, int on)
{
struct hpet_dev *devp;
+ int r = hpet_alloc_timer(file);
+ if (r < 0)
+ return r;
+
devp = file->private_data;
if (fasync_helper(fd, file, on, &devp->hd_async_queue) >= 0)
@@ -401,6 +429,9 @@ static int hpet_release(struct inode *inode, struct file *file)
devp = file->private_data;
timer = devp->hd_timer;
+ if (!timer)
+ goto out;
+
spin_lock_irq(&hpet_lock);
writeq((readq(&timer->hpet_config) & ~Tn_INT_ENB_CNF_MASK),
@@ -425,7 +456,7 @@ static int hpet_release(struct inode *inode, struct file *file)
if (irq)
free_irq(irq, devp);
-
+out:
file->private_data = NULL;
return 0;
}
@@ -438,6 +469,10 @@ hpet_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
{
struct hpet_dev *devp;
+ int r = hpet_alloc_timer(file);
+ if (r < 0)
+ return r;
+
devp = file->private_data;
return hpet_ioctl_common(devp, cmd, arg, 0);
}
@@ -570,6 +605,9 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel)
break;
case HPET_IE_ON:
return hpet_ioctl_ieon(devp);
+ case HPET_ALLOC_TIMER:
+ /* nothing to do */
+ return 0;
default:
return -EINVAL;
}
@@ -794,7 +832,11 @@ int hpet_alloc(struct hpet_data *hdp)
return 0;
}
- siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) *
+ /*
+ * last hpet_dev will have null timer pointer, gives timer-neutral
+ * representation of block
+ */
+ siz = sizeof(struct hpets) + ((hdp->hd_nirqs) *
sizeof(struct hpet_dev));
hpetp = kzalloc(siz, GFP_KERNEL);
@@ -860,13 +902,16 @@ int hpet_alloc(struct hpet_data *hdp)
writeq(mcfg, &hpet->hpet_config);
}
- for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer; i++, devp++) {
+ for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer + 1;
+ i++, devp++) {
struct hpet_timer __iomem *timer;
- timer = &hpet->hpet_timers[devp - hpetp->hp_dev];
-
devp->hd_hpets = hpetp;
devp->hd_hpet = hpet;
+ if (i == hpetp->hp_ntimer)
+ continue;
+
+ timer = &hpet->hpet_timers[devp - hpetp->hp_dev];
devp->hd_timer = timer;
/*
diff --git a/include/linux/hpet.h b/include/linux/hpet.h
index 219ca4f..d690c0f 100644
--- a/include/linux/hpet.h
+++ b/include/linux/hpet.h
@@ -125,6 +125,7 @@ struct hpet_info {
#define HPET_EPI _IO('h', 0x04) /* enable periodic */
#define HPET_DPI _IO('h', 0x05) /* disable periodic */
#define HPET_IRQFREQ _IOW('h', 0x6, unsigned long) /* IRQFREQ usec */
+#define HPET_ALLOC_TIMER _IO('h', 0x7)
#define MAX_HPET_TBS 8 /* maximum hpet timer blocks */
next prev parent reply other threads:[~2010-03-08 0:04 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-01 5:30 [PATCH] hpet: factor timer allocate from open Magnus Lynch
2010-03-01 9:59 ` Clemens Ladisch
2010-03-01 20:24 ` Magnus Lynch
2010-03-01 20:59 ` john stultz
2010-03-03 9:07 ` Magnus Lynch
2010-03-03 16:26 ` john stultz
2010-03-10 2:47 ` Magnus Lynch
2010-03-04 2:59 ` Magnus Lynch
2010-03-04 8:43 ` Clemens Ladisch
2010-03-08 0:04 ` Magnus Lynch [this message]
2010-03-16 16:01 ` Clemens Ladisch
2010-03-18 19:11 ` Andrew Morton
2010-03-19 4:06 ` Magnus Lynch
2010-03-22 22:21 ` Andrew Morton
2010-03-23 2:02 ` Magnus Lynch
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4b943f17.4902be0a.5bd5.0917@mx.google.com \
--to=maglyx@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=clemens@ladisch.de \
--cc=ebiederm@xmission.com \
--cc=linux-kernel@vger.kernel.org \
--cc=paul.gortmaker@windriver.com \
--cc=suresh.b.siddha@intel.com \
--cc=tglx@linutronix.de \
--cc=venkatesh.pallipadi@intel.com \
--cc=vojtech@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.