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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox