From: Dmitry Torokhov <dtor_core-yWtbtysYrB+LZ21kGMrzwg@public.gmane.org>
To: acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Cc: Len Brown <len.brow-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Subject: [PATCH 4/4] allow multiple /proc/acpi/event readers
Date: Tue, 24 Aug 2004 01:39:33 -0500 [thread overview]
Message-ID: <200408240139.36616.dtor_core@ameritech.net> (raw)
In-Reply-To: <200408240137.55691.dtor_core-yWtbtysYrB+LZ21kGMrzwg@public.gmane.org>
===================================================================
ChangeSet@1.1845, 2004-08-24 01:12:17-05:00, dtor_core-yWtbtysYrB+LZ21kGMrzwg@public.gmane.org
ACPI: allow multiple readers for /proc/acpi/event, limit number
of pending events to 64 so if reader is stuck ACPI won't
consume all memory.
Signed-off-by: Dmitry Torokhov <dtor-JGs/UdohzUI@public.gmane.org>
drivers/acpi/event.c | 148 +++++++++++++++++++++-------------------------
include/acpi/acpi_event.h | 1
2 files changed, 69 insertions(+), 80 deletions(-)
===================================================================
diff -Nru a/drivers/acpi/event.c b/drivers/acpi/event.c
--- a/drivers/acpi/event.c 2004-08-24 01:17:52 -05:00
+++ b/drivers/acpi/event.c 2004-08-24 01:17:52 -05:00
@@ -16,10 +16,20 @@
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME ("event")
+#define ACPI_EVENT_BUFFER_SIZE 64
+struct acpi_event_reader {
+ struct acpi_bus_event buffer[ACPI_EVENT_BUFFER_SIZE];
+ int head, tail;
+ char str[ACPI_MAX_STRING];
+ int chars_remaining;
+ char *ptr;
+ struct list_head node;
+};
+
DECLARE_WAIT_QUEUE_HEAD(acpi_event_queue);
-LIST_HEAD(acpi_event_list);
+static LIST_HEAD(acpi_event_reader_list);
static spinlock_t acpi_event_lock = SPIN_LOCK_UNLOCKED;
-static int event_is_open;
+static int reader_count;
int
acpi_generate_event(
@@ -27,9 +37,9 @@
u8 type,
int data)
{
- struct acpi_bus_event *event;
- unsigned long flags;
- int result = 0;
+ struct acpi_bus_event event;
+ struct acpi_event_reader *reader;
+ unsigned long flags;
ACPI_FUNCTION_TRACE("acpi_generate_event");
@@ -38,75 +48,66 @@
spin_lock_irqsave(&acpi_event_lock, flags);
- /* drop event on the floor if no one's listening */
- if (!event_is_open)
- goto out;
-
- event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
- if (!event) {
- result = -ENOMEM;
- goto out;
+ strcpy(event.device_class, device->pnp.device_class);
+ strcpy(event.bus_id, device->pnp.bus_id);
+ event.type = type;
+ event.data = data;
+
+ list_for_each_entry(reader, &acpi_event_reader_list, node) {
+ reader->buffer[reader->head] = event;
+ reader->head = (reader->head + 1) & (ACPI_EVENT_BUFFER_SIZE - 1);
}
+ spin_unlock_irqrestore(&acpi_event_lock, flags);
- strcpy(event->device_class, device->pnp.device_class);
- strcpy(event->bus_id, device->pnp.bus_id);
- event->type = type;
- event->data = data;
-
- list_add_tail(&event->node, &acpi_event_list);
wake_up_interruptible(&acpi_event_queue);
-out:
- spin_unlock_irqrestore(&acpi_event_lock, flags);
- return_VALUE(result);
+ return_VALUE(0);
}
-static struct acpi_bus_event *acpi_fetch_event(void)
+static void acpi_fetch_event(struct acpi_event_reader *reader)
{
- struct acpi_bus_event *event = NULL;
+ struct acpi_bus_event *event;
unsigned long flags;
ACPI_FUNCTION_TRACE("acpi_fetch_event");
spin_lock_irqsave(&acpi_event_lock, flags);
- if (!list_empty(&acpi_event_list)) {
- event = list_entry(acpi_event_list.next,
- struct acpi_bus_event, node);
- list_del(&event->node);
+ if (reader->head != reader->tail) {
+ event = &reader->buffer[reader->tail];
+ reader->tail = (reader->tail + 1) & (ACPI_EVENT_BUFFER_SIZE - 1);
+
+ reader->chars_remaining =
+ snprintf(reader->str, ACPI_MAX_STRING,
+ "%s %s %08x %08x\n",
+ event->device_class ?
+ event->device_class : "<unknown>",
+ event->bus_id ? event->bus_id : "<unknown>",
+ event->type, event->data);
+
}
spin_unlock_irqrestore(&acpi_event_lock, flags);
- return_PTR(event);
+ return_VOID;
}
static int
acpi_system_open_event(struct inode *inode, struct file *file)
{
- int rc = 0;
-
- spin_lock_irq(&acpi_event_lock);
+ struct acpi_event_reader *reader;
- if (event_is_open) {
- rc = -EBUSY;
- goto out;
- }
+ if (!(reader = kmalloc(sizeof(struct acpi_event_reader), GFP_KERNEL)))
+ return -ENOMEM;
- event_is_open = 1;
+ memset(reader, 0, sizeof(struct acpi_event_reader));
+ file->private_data = reader;
-out:
+ spin_lock_irq(&acpi_event_lock);
+ list_add_tail(&reader->node, &acpi_event_reader_list);
+ reader_count++;
spin_unlock_irq(&acpi_event_lock);
- return rc;
-}
-
-static inline int
-event_to_string(struct acpi_bus_event *event, char *buffer)
-{
- return sprintf(buffer, "%s %s %08x %08x\n",
- event->device_class ? event->device_class : "<unknown>",
- event->bus_id ? event->bus_id : "<unknown>",
- event->type, event->data);
+ return 0;
}
static ssize_t
@@ -116,42 +117,33 @@
size_t count,
loff_t *ppos)
{
- int result;
- struct acpi_bus_event *event;
- static char str[ACPI_MAX_STRING];
- static int chars_remaining;
- static char *ptr;
-
+ struct acpi_event_reader *reader = file->private_data;
+ int result;
ACPI_FUNCTION_TRACE("acpi_system_read_event");
- if (!chars_remaining) {
- if (list_empty(&acpi_event_list) &&
- (file->f_flags & O_NONBLOCK))
+ if (reader->chars_remaining == 0) {
+ if (reader->head == reader->tail && (file->f_flags & O_NONBLOCK))
return_VALUE(-EAGAIN);
result = wait_event_interruptible(acpi_event_queue,
- !list_empty(&acpi_event_list));
+ reader->head != reader->tail);
if (result)
return_VALUE(result);
- if ((event = acpi_fetch_event()) == NULL)
- return_VALUE(0);
-
- chars_remaining = event_to_string(event, str);
- ptr = str;
- kfree(event);
+ acpi_fetch_event(reader);
+ reader->ptr = reader->str;
}
- if (chars_remaining < count)
- count = chars_remaining;
+ if (reader->chars_remaining < count)
+ count = reader->chars_remaining;
- if (copy_to_user(buffer, ptr, count))
+ if (copy_to_user(buffer, reader->ptr, count))
return_VALUE(-EFAULT);
*ppos += count;
- chars_remaining -= count;
- ptr += count;
+ reader->chars_remaining -= count;
+ reader->ptr += count;
return_VALUE(count);
}
@@ -159,19 +151,15 @@
static int
acpi_system_close_event(struct inode *inode, struct file *file)
{
- struct acpi_bus_event *event, *next;
+ struct acpi_event_reader *reader = file->private_data;
spin_lock_irq(&acpi_event_lock);
+ list_del(&reader->node);
+ reader_count--;
+ spin_unlock_irq(&acpi_event_lock);
- /* We won't be interested in old events, will we? */
- list_for_each_entry_safe(event, next, &acpi_event_list, node) {
- list_del(&event->node);
- kfree(event);
- }
-
- event_is_open = 0;
+ kfree(reader);
- spin_unlock_irq(&acpi_event_lock);
return 0;
}
@@ -180,8 +168,10 @@
struct file *file,
poll_table *wait)
{
+ struct acpi_event_reader *reader = file->private_data;
+
poll_wait(file, &acpi_event_queue, wait);
- if (!list_empty(&acpi_event_list))
+ if (reader->head != reader->tail)
return POLLIN | POLLRDNORM;
return 0;
}
diff -Nru a/include/acpi/acpi_event.h b/include/acpi/acpi_event.h
--- a/include/acpi/acpi_event.h 2004-08-24 01:17:52 -05:00
+++ b/include/acpi/acpi_event.h 2004-08-24 01:17:52 -05:00
@@ -31,7 +31,6 @@
#include <acpi/acpi_bus.h>
struct acpi_bus_event {
- struct list_head node;
acpi_device_class device_class;
acpi_bus_id bus_id;
u32 type;
-------------------------------------------------------
SF.Net email is sponsored by Shop4tech.com-Lowest price on Blank Media
100pk Sonic DVD-R 4x for only $29 -100pk Sonic DVD+R for only $33
Save 50% off Retail on Ink & Toner - Free Shipping and Free Gift.
http://www.shop4tech.com/z/Inkjet_Cartridges/9_108_r285
next prev parent reply other threads:[~2004-08-24 6:39 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-08-24 6:34 [PATCH 1/4] properly create kobjects in acpi/scan.c Dmitry Torokhov
[not found] ` <200408240134.16962.dtor_core-yWtbtysYrB+LZ21kGMrzwg@public.gmane.org>
2004-08-24 6:36 ` [PATCH 2/4] event code fixes/cleanup Dmitry Torokhov
[not found] ` <200408240136.46113.dtor_core-yWtbtysYrB+LZ21kGMrzwg@public.gmane.org>
2004-08-24 6:37 ` [PATCH 3/4] use acpi_subsys.rwsem in acpi/scan.c Dmitry Torokhov
[not found] ` <200408240137.55691.dtor_core-yWtbtysYrB+LZ21kGMrzwg@public.gmane.org>
2004-08-24 6:39 ` Dmitry Torokhov [this message]
2004-08-24 15:23 ` [PATCH 1/4] properly create kobjects " Hiroshi Miura
[not found] ` <87zn4ky2zr.wl%miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org>
2004-08-24 16:15 ` Mattia Dongili
2004-08-24 17:03 ` Dmitry Torokhov
2004-08-24 19:50 ` Len Brown
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=200408240139.36616.dtor_core@ameritech.net \
--to=dtor_core-ywtbtysyrb+lz21kgmrzwg@public.gmane.org \
--cc=acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=len.brow-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
/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