* [patch 2/4] kernel salinfo changes
@ 2003-10-30 8:34 Keith Owens
0 siblings, 0 replies; only message in thread
From: Keith Owens @ 2003-10-30 8:34 UTC (permalink / raw)
To: linux-ia64
patch 2 - Clean up kernel salinfo state checking.
Different bits of arch/ia64/kernel/salinfo.c checked different fields
to determine what state the processing was in. Rationalise them all to
a single state flag. This also positions for the ability to extend
kernel salinfo to handle more operations.
Get rid of the new_read flag, read the record when the user asks for it
or after clearing a record.
diff -ur 2.4.23-pre8-cset-1.1069.1.143-to-1.1108-salinfo1/arch/ia64/kernel/salinfo.c 2.4.23-pre8-cset-1.1069.1.143-to-1.1108-salinfo2/arch/ia64/kernel/salinfo.c
--- 2.4.23-pre8-cset-1.1069.1.143-to-1.1108-salinfo1/arch/ia64/kernel/salinfo.c Thu Oct 30 17:06:19 2003
+++ 2.4.23-pre8-cset-1.1069.1.143-to-1.1108-salinfo2/arch/ia64/kernel/salinfo.c Thu Oct 30 18:40:02 2003
@@ -85,6 +85,36 @@
int cpu;
};
+/* State transitions. Actions are :-
+ * Write "read <cpunum>" to the data file.
+ * Write "clear <cpunum>" to the data file.
+ * Read from the data file.
+ * Close the data file.
+ *
+ * Start state is NO_DATA.
+ *
+ * NO_DATA
+ * write "read <cpunum>" -> NO_DATA or LOG_RECORD.
+ * write "clear <cpunum>" -> NO_DATA or LOG_RECORD.
+ * read data -> return EOF.
+ * close -> unchanged. Free record areas.
+ *
+ * LOG_RECORD
+ * write "read <cpunum>" -> NO_DATA or LOG_RECORD.
+ * write "clear <cpunum>" -> NO_DATA or LOG_RECORD.
+ * read data -> return the INIT/MCA/CMC/CPE record.
+ * close -> unchanged. Keep record areas.
+ *
+ * Closing the data file does not change the state. This allows shell scripts
+ * to manipulate salinfo data, each shell redirection opens the file, does one
+ * action then closes it again. The record areas are only freed at close when
+ * the state is NO_DATA.
+ */
+enum salinfo_state {
+ STATE_NO_DATA,
+ STATE_LOG_RECORD,
+};
+
struct salinfo_data {
volatile cpumask_t cpu_event; /* which cpus have outstanding events */
struct semaphore sem; /* count of cpus with outstanding events (bits set in cpu_event) */
@@ -93,9 +123,8 @@
int open; /* single-open to prevent races */
u8 type;
u8 saved_num; /* using a saved record? */
- u8 new_read; /* start of a new read? */
+ enum salinfo_state state :8; /* processing state */
u8 padding;
- int cpu_read; /* "current" cpu for reads */
int cpu_check; /* next CPU to check */
struct salinfo_data_saved data_saved[5];/* save last 5 records from mca.c, must be < 255 */
};
@@ -241,7 +270,8 @@
data->open = 1;
spin_unlock(&data_lock);
- if (!(data->log_buffer = vmalloc(ia64_sal_get_state_info_size(data->type)))) {
+ if (data->state = STATE_NO_DATA &&
+ !(data->log_buffer = vmalloc(ia64_sal_get_state_info_size(data->type)))) {
data->open = 0;
return -ENOMEM;
}
@@ -255,8 +285,10 @@
struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip;
struct salinfo_data *data = entry->data;
- vfree(data->log_buffer);
- data->log_buffer = NULL;
+ if (data->state = STATE_NO_DATA) {
+ vfree(data->log_buffer);
+ data->log_buffer = NULL;
+ }
spin_lock(&data_lock);
data->open = 0;
spin_unlock(&data_lock);
@@ -283,19 +315,18 @@
}
static void
-salinfo_log_new_read(struct salinfo_data *data)
+salinfo_log_new_read(int cpu, struct salinfo_data *data)
{
struct salinfo_data_saved *data_saved;
unsigned long flags;
int i;
int saved_size = ARRAY_SIZE(data->data_saved);
- data->new_read = 0;
data->saved_num = 0;
spin_lock_irqsave(&data_saved_lock, flags);
retry:
for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) {
- if (data_saved->buffer && data_saved->cpu = data->cpu_read) {
+ if (data_saved->buffer && data_saved->cpu = cpu) {
sal_log_record_header_t *rh = (sal_log_record_header_t *)(data_saved->buffer);
data->log_size = data_saved->size;
memcpy(data->log_buffer, rh, data->log_size);
@@ -312,7 +343,8 @@
spin_unlock_irqrestore(&data_saved_lock, flags);
if (!data->saved_num)
- call_on_cpu(data->cpu_read, salinfo_log_read_cpu, data);
+ call_on_cpu(cpu, salinfo_log_read_cpu, data);
+ data->state = data->log_size ? STATE_LOG_RECORD : STATE_NO_DATA;
}
static ssize_t
@@ -350,11 +382,11 @@
static int
salinfo_log_clear(struct salinfo_data *data, int cpu)
{
+ data->state = STATE_NO_DATA;
if (!test_bit(cpu, &data->cpu_event))
return 0;
down(&data->sem);
clear_bit(cpu, &data->cpu_event);
- data->log_size = 0;
if (data->saved_num) {
unsigned long flags;
spin_lock_irqsave(&data_saved_lock, flags);
@@ -365,10 +397,9 @@
call_on_cpu(cpu, salinfo_log_clear_cpu, data);
/* clearing a record may make a new record visible */
- data->cpu_read = cpu;
- salinfo_log_new_read(data);
- if (data->log_size &&
- !test_and_set_bit(data->cpu_read, &data->cpu_event))
+ salinfo_log_new_read(cpu, data);
+ if (data->state = STATE_LOG_RECORD &&
+ !test_and_set_bit(cpu, &data->cpu_event))
up(&data->sem);
return 0;
}
@@ -390,8 +421,7 @@
return -EFAULT;
if (sscanf(cmd, "read %d", &cpu) = 1) {
- data->cpu_read = cpu;
- data->new_read = 1;
+ salinfo_log_new_read(cpu, data);
} else if (sscanf(cmd, "clear %d", &cpu) = 1) {
int ret;
if ((ret = salinfo_log_clear(data, cpu)))
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2003-10-30 8:34 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-10-30 8:34 [patch 2/4] kernel salinfo changes Keith Owens
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox