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 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.