linux.kernel - 26 new messages in 5 topics - digest
linux.kernel
http://groups.google.com/group/linux.kernel?hl=en
Today's topics:
* tracing: simplify memory recycle of trace_define_field - 1 messages, 1
author
http://groups.google.com/group/linux.kernel/t/9c740a21503888f9?hl=en
* Patch for tracing c states (power_end) on x86 - 2 messages, 2 authors
http://groups.google.com/group/linux.kernel/t/91e464354797bdad?hl=en
* [PATCH] codepage conversion of kernel parameter line - 3 messages, 1 author
http://groups.google.com/group/linux.kernel/t/e80b459b86a77ac5?hl=en
* s390 patch queue for 2.6.34 - 19 messages, 1 author
http://groups.google.com/group/linux.kernel/t/e3cba9cf6d8b02fa?hl=en
* linux-next: Tree for February 24 - 1 messages, 1 author
http://groups.google.com/group/linux.kernel/t/f27d730c9375502b?hl=en
==============================================================================
TOPIC: tracing: simplify memory recycle of trace_define_field
http://groups.google.com/group/linux.kernel/t/9c740a21503888f9?hl=en
==============================================================================
== 1 of 1 ==
Date: Wed, Feb 24 2010 12:30 am
From: Wenji Huang
On 02/24/2010 04:04 PM, Li Zefan wrote:
> Wenji Huang wrote:
>> Discard freeing field->type since it's not necessary and may be hazard.
>>
>
> It's redundant, but it's safe, because if we run into this failure path,
> field->type is always NULL.
There are two entries to failure path, field->name == NULL or
field->type == NULL. And allocating for field->name is before field->type.
IMHO, field->type is not fixed after initialization, it's
not safe if field->name==NULL goes to failure path.
Regards,
Wenji
>
>> Signed-off-by: Wenji Huang<wenji.huang@oracle.com>
>
> Reviewed-by: Li Zefan<lizf@cn.fujitsu.com>
>
>> ---
>> kernel/trace/trace_events.c | 4 +---
>> 1 files changed, 1 insertions(+), 3 deletions(-)
>>
>> diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
>> index c2a3077..3f972ad 100644
>> --- a/kernel/trace/trace_events.c
>> +++ b/kernel/trace/trace_events.c
>> @@ -60,10 +60,8 @@ int trace_define_field(struct ftrace_event_call *call, const char *type,
>> return 0;
>>
>> err:
>> - if (field) {
>> + if (field)
>> kfree(field->name);
>> - kfree(field->type);
>> - }
>> kfree(field);
>>
>> return -ENOMEM;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
==============================================================================
TOPIC: Patch for tracing c states (power_end) on x86
http://groups.google.com/group/linux.kernel/t/91e464354797bdad?hl=en
==============================================================================
== 1 of 2 ==
Date: Wed, Feb 24 2010 12:40 am
From: Li Zefan
Robert Schöne wrote:
> Hello,
>
> Since noone replied to my last mail (Febr. 15th, 11:42), describing the
> way to fix the missing c-state tracing, here's a patch.
> Maybe its easier that way.
>
> (I used the perf-fixes-for-linus git tree to obtain a
> more-then-up-to-date version)
>
> Bye Robert
>
>
> diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
> index 02d6780..b1cfb88 100644
> --- a/arch/x86/kernel/process.c
> +++ b/arch/x86/kernel/process.c
> @@ -384,6 +384,7 @@ void default_idle(void)
> else
> local_irq_enable();
> current_thread_info()->status |= TS_POLLING;
> + trace_power_end(1);
> } else {
> local_irq_enable();
> /* loop is done by the caller */
> @@ -451,6 +452,7 @@ void mwait_idle_with_hints(unsigned long ax,
> unsigned long cx)
> if (!need_resched())
> __mwait(ax, cx);
> }
> + trace_power_end((ax>>4)+1);
The only argument of trace_power_end() is a dummy, so you can just
pass 0 or 1 to the trace hook, actually better pass 0 to be
consistent with other parts.
The dummy argument can't be eliminated, because the macros that
automatically generates racing code have some limitations, and
seems it's not so easy to get over.
> }
>
> /* Default MONITOR/MWAIT with no hints, used for default C1 state */
> @@ -467,6 +469,7 @@ static void mwait_idle(void)
> __sti_mwait(0, 0);
> else
> local_irq_enable();
> + trace_power_end(1);
> } else
> local_irq_enable();
> }
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
== 2 of 2 ==
Date: Wed, Feb 24 2010 12:50 am
From: Robert Schöne
Hi,
I tried to pass 0 in "my" sleep routine "static void mwait_idle(void)"
Which led to the following behaviour:
The event was reported on /sys/kernel/debug/tracing, but still not
for sys_perf_open.
As 1 had been the argument which led to a working tracing, I assumed,
that the argument should be the same as the 2nd arg of the last
power_start event.
Since this argument had been 1 in my case, it worked for me. However, 0
did not.
Bye Robert
Am Mittwoch, den 24.02.2010, 16:36 +0800 schrieb Li Zefan:
> Robert Schöne wrote:
> > Hello,
> >
> > Since noone replied to my last mail (Febr. 15th, 11:42), describing the
> > way to fix the missing c-state tracing, here's a patch.
> > Maybe its easier that way.
> >
> > (I used the perf-fixes-for-linus git tree to obtain a
> > more-then-up-to-date version)
> >
> > Bye Robert
> >
> >
> > diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
> > index 02d6780..b1cfb88 100644
> > --- a/arch/x86/kernel/process.c
> > +++ b/arch/x86/kernel/process.c
> > @@ -384,6 +384,7 @@ void default_idle(void)
> > else
> > local_irq_enable();
> > current_thread_info()->status |= TS_POLLING;
> > + trace_power_end(1);
> > } else {
> > local_irq_enable();
> > /* loop is done by the caller */
> > @@ -451,6 +452,7 @@ void mwait_idle_with_hints(unsigned long ax,
> > unsigned long cx)
> > if (!need_resched())
> > __mwait(ax, cx);
> > }
> > + trace_power_end((ax>>4)+1);
>
> The only argument of trace_power_end() is a dummy, so you can just
> pass 0 or 1 to the trace hook, actually better pass 0 to be
> consistent with other parts.
>
> The dummy argument can't be eliminated, because the macros that
> automatically generates racing code have some limitations, and
> seems it's not so easy to get over.
>
> > }
> >
> > /* Default MONITOR/MWAIT with no hints, used for default C1 state */
> > @@ -467,6 +469,7 @@ static void mwait_idle(void)
> > __sti_mwait(0, 0);
> > else
> > local_irq_enable();
> > + trace_power_end(1);
> > } else
> > local_irq_enable();
> > }
> >
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
------------------------- Mail from Febr. 15th --------------------
Hi,
I have a question regarding the event "power/power_end".
For the standard linux kernel (2.6.32.8), it's just not reported -
neither for the /sys/kernel/debug/tracing nor for the sys_perf_open
approach.
System:
Intel Core 2 Quad,
Kernel 2.6.32.8,
for sys_perf_open:always using sampling counters,
(Kernel 2.6.33-rcX should show the same behavior)
After finding "my" c-state procedure in arch/x86/kernel/process.c
(which was "static void mwait_idle(void)" btw), I added a
trace_power_end call on the correct line:
...
else
local_irq_enable();
} else
...
->
...
else
local_irq_enable();
trace_power_end(0);
} else
...
Now the event was reported on /sys/kernel/debug/tracing, but still not
for sys_perf_open.
Then I had the idea, that trace_power_end's argument should be the same
as the 2nd argument of the previous power_start.
That worked.
However, things to be done are: add trace_power_end's to some
process.c's procedures.
Bye Robert
-------------------------End of Mail of Febr. 15th --------------------
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
==============================================================================
TOPIC: [PATCH] codepage conversion of kernel parameter line
http://groups.google.com/group/linux.kernel/t/e80b459b86a77ac5?hl=en
==============================================================================
== 1 of 3 ==
Date: Wed, Feb 24 2010 12:50 am
From: Martin Schwidefsky
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
Move the ebcdic to ascii conversion of the kernel parameter line from
head.S to early.c and convert the assembler code to C.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---
arch/s390/kernel/early.c | 13 ++++++++++++-
arch/s390/kernel/head.S | 18 +-----------------
2 files changed, 13 insertions(+), 18 deletions(-)
Index: quilt-2.6/arch/s390/kernel/early.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/early.c 2010-02-24 09:44:25.000000000 +0100
+++ quilt-2.6/arch/s390/kernel/early.c 2010-02-24 09:44:28.000000000 +0100
@@ -405,8 +405,19 @@
static void __init setup_boot_command_line(void)
{
+ int i;
+
+ /* convert arch command line to ascii */
+ for (i = 0; i < ARCH_COMMAND_LINE_SIZE; i++)
+ if (COMMAND_LINE[i] & 0x80)
+ break;
+ if (i < ARCH_COMMAND_LINE_SIZE)
+ EBCASC(COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
+ COMMAND_LINE[ARCH_COMMAND_LINE_SIZE-1] = 0;
+
/* copy arch command line */
- strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
+ strlcpy(boot_command_line, strstrip(COMMAND_LINE),
+ ARCH_COMMAND_LINE_SIZE);
/* append IPL PARM data to the boot command line */
if (MACHINE_IS_VM)
Index: quilt-2.6/arch/s390/kernel/head.S
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/head.S 2010-02-24 09:44:26.000000000 +0100
+++ quilt-2.6/arch/s390/kernel/head.S 2010-02-24 09:44:28.000000000 +0100
@@ -287,19 +287,7 @@
bz .Lagain1 # skip dateset trailer
la %r5,0(%r4,%r2)
lr %r3,%r2
-.Lidebc:
- tm 0(%r5),0x80 # high order bit set ?
- bo .Ldocv # yes -> convert from EBCDIC
- ahi %r5,-1
- bct %r3,.Lidebc
- b .Lnocv
-.Ldocv:
- l %r3,.Lcvtab
- tr 0(256,%r4),0(%r3) # convert parameters to ascii
- tr 256(256,%r4),0(%r3)
- tr 512(256,%r4),0(%r3)
- tr 768(122,%r4),0(%r3)
-.Lnocv: la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
+ la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
mvc 0(256,%r3),0(%r4)
mvc 256(256,%r3),256(%r4)
mvc 512(256,%r3),512(%r4)
@@ -383,7 +371,6 @@
.Linitrd:.long _end + 0x400000 # default address of initrd
.Lparm: .long PARMAREA
.Lstartup: .long startup
-.Lcvtab:.long _ebcasc # ebcdic to ascii table
.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
.byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
.byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold"
@@ -416,13 +403,10 @@
.sk8x8:
mvc 0(240,%r8),0(%r9) # copy iplparms into buffer
.gotr:
- l %r10,.tbl # EBCDIC to ASCII table
- tr 0(240,%r8),0(%r10)
slr %r0,%r0
st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
j startup # continue with startup
-.tbl: .long _ebcasc # translate table
.cmd: .long COMMAND_LINE # address of command line buffer
.parm: .long PARMAREA
.lowcase:
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
== 2 of 3 ==
Date: Wed, Feb 24 2010 12:50 am
From: Martin Schwidefsky
From: Jan Glauber <jang@linux.vnet.ibm.com>
Add counters for the number of processed SBALs. The numbers summarize
how many SBALs were processed at each queue scan and indicate the
utilization of the queue. Furthermore the number of unsuccessfull
queue scans, SBAL errors and the total number of processed
SBALs are accounted.
Also regroup struct qdio_q to move read-mostly and write-mostly data
into different cachelines.
Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---
drivers/s390/cio/qdio.h | 85 ++++++++++++++++++++++++++----------------
drivers/s390/cio/qdio_debug.c | 23 ++++++++++-
drivers/s390/cio/qdio_main.c | 26 ++++++++++++
3 files changed, 101 insertions(+), 33 deletions(-)
Index: quilt-2.6/drivers/s390/cio/qdio_debug.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/qdio_debug.c 2010-02-24 09:28:13.000000000 +0100
+++ quilt-2.6/drivers/s390/cio/qdio_debug.c 2010-02-24 09:44:25.000000000 +0100
@@ -60,7 +60,7 @@
seq_printf(m, "ftc: %d last_move: %d\n", q->first_to_check, q->last_move);
seq_printf(m, "polling: %d ack start: %d ack count: %d\n",
q->u.in.polling, q->u.in.ack_start, q->u.in.ack_count);
- seq_printf(m, "slsb buffer states:\n");
+ seq_printf(m, "SBAL states:\n");
seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n");
for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {
@@ -97,6 +97,20 @@
}
seq_printf(m, "\n");
seq_printf(m, "|64 |72 |80 |88 |96 |104 |112 | 127|\n");
+
+ seq_printf(m, "\nSBAL statistics:");
+ if (!q->irq_ptr->perf_stat_enabled) {
+ seq_printf(m, " disabled\n");
+ return 0;
+ }
+
+ seq_printf(m, "\n1 2.. 4.. 8.. "
+ "16.. 32.. 64.. 127\n");
+ for (i = 0; i < ARRAY_SIZE(q->q_stats.nr_sbals); i++)
+ seq_printf(m, "%-10u ", q->q_stats.nr_sbals[i]);
+ seq_printf(m, "\nError NOP Total\n%-10u %-10u %-10u\n\n",
+ q->q_stats.nr_sbal_error, q->q_stats.nr_sbal_nop,
+ q->q_stats.nr_sbal_total);
return 0;
}
@@ -181,9 +195,10 @@
{
struct seq_file *seq = file->private_data;
struct qdio_irq *irq_ptr = seq->private;
+ struct qdio_q *q;
unsigned long val;
char buf[8];
- int ret;
+ int ret, i;
if (!irq_ptr)
return 0;
@@ -201,6 +216,10 @@
case 0:
irq_ptr->perf_stat_enabled = 0;
memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat));
+ for_each_input_queue(irq_ptr, q, i)
+ memset(&q->q_stats, 0, sizeof(q->q_stats));
+ for_each_output_queue(irq_ptr, q, i)
+ memset(&q->q_stats, 0, sizeof(q->q_stats));
break;
case 1:
irq_ptr->perf_stat_enabled = 1;
Index: quilt-2.6/drivers/s390/cio/qdio.h
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/qdio.h 2010-02-24 09:28:13.000000000 +0100
+++ quilt-2.6/drivers/s390/cio/qdio.h 2010-02-24 09:44:25.000000000 +0100
@@ -210,16 +210,25 @@
unsigned int sqbs_partial;
};
+struct qdio_queue_perf_stat {
+ /*
+ * Sorted into order-2 buckets: 1, 2-3, 4-7, ... 64-127, 128.
+ * Since max. 127 SBALs are scanned reuse entry for 128 as queue full
+ * aka 127 SBALs found.
+ */
+ unsigned int nr_sbals[8];
+ unsigned int nr_sbal_error;
+ unsigned int nr_sbal_nop;
+ unsigned int nr_sbal_total;
+};
+
struct qdio_input_q {
/* input buffer acknowledgement flag */
int polling;
-
/* first ACK'ed buffer */
int ack_start;
-
/* how much sbals are acknowledged with qebsm */
int ack_count;
-
/* last time of noticing incoming data */
u64 timestamp;
};
@@ -227,40 +236,27 @@
struct qdio_output_q {
/* PCIs are enabled for the queue */
int pci_out_enabled;
-
/* IQDIO: output multiple buffers (enhanced SIGA) */
int use_enh_siga;
-
/* timer to check for more outbound work */
struct timer_list timer;
};
+/*
+ * Note on cache alignment: grouped slsb and write mostly data at the beginning
+ * sbal[] is read-only and starts on a new cacheline followed by read mostly.
+ */
struct qdio_q {
struct slsb slsb;
+
union {
struct qdio_input_q in;
struct qdio_output_q out;
} u;
- /* queue number */
- int nr;
-
- /* bitmask of queue number */
- int mask;
-
- /* input or output queue */
- int is_input_q;
-
- /* list of thinint input queues */
- struct list_head entry;
-
- /* upper-layer program handler */
- qdio_handler_t (*handler);
-
/*
* inbound: next buffer the program should check for
- * outbound: next buffer to check for having been processed
- * by the card
+ * outbound: next buffer to check if adapter processed it
*/
int first_to_check;
@@ -273,16 +269,32 @@
/* number of buffers in use by the adapter */
atomic_t nr_buf_used;
- struct qdio_irq *irq_ptr;
- struct dentry *debugfs_q;
- struct tasklet_struct tasklet;
-
/* error condition during a data transfer */
unsigned int qdio_error;
- struct sl *sl;
- struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q];
+ struct tasklet_struct tasklet;
+ struct qdio_queue_perf_stat q_stats;
+
+ struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q] ____cacheline_aligned;
+ /* queue number */
+ int nr;
+
+ /* bitmask of queue number */
+ int mask;
+
+ /* input or output queue */
+ int is_input_q;
+
+ /* list of thinint input queues */
+ struct list_head entry;
+
+ /* upper-layer program handler */
+ qdio_handler_t (*handler);
+
+ struct dentry *debugfs_q;
+ struct qdio_irq *irq_ptr;
+ struct sl *sl;
/*
* Warning: Leave this member at the end so it won't be cleared in
* qdio_fill_qs. A page is allocated under this pointer and used for
@@ -341,9 +353,20 @@
(irq->qib.qfmt == QDIO_IQDIO_QFMT || \
css_general_characteristics.aif_osa)
-#define qperf(qdev,attr) qdev->perf_stat.attr
-#define qperf_inc(q,attr) if (q->irq_ptr->perf_stat_enabled) \
- q->irq_ptr->perf_stat.attr++
+#define qperf(__qdev, __attr) ((__qdev)->perf_stat.(__attr))
+
+#define qperf_inc(__q, __attr) \
+({ \
+ struct qdio_irq *qdev = (__q)->irq_ptr; \
+ if (qdev->perf_stat_enabled) \
+ (qdev->perf_stat.__attr)++; \
+})
+
+static inline void account_sbals_error(struct qdio_q *q, int count)
+{
+ q->q_stats.nr_sbal_error += count;
+ q->q_stats.nr_sbal_total += count;
+}
/* the highest iqdio queue is used for multicast */
static inline int multicast_outbound(struct qdio_q *q)
Index: quilt-2.6/drivers/s390/cio/qdio_main.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/qdio_main.c 2010-02-24 09:28:13.000000000 +0100
+++ quilt-2.6/drivers/s390/cio/qdio_main.c 2010-02-24 09:44:25.000000000 +0100
@@ -392,6 +392,20 @@
set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
}
+static inline void account_sbals(struct qdio_q *q, int count)
+{
+ int pos = 0;
+
+ q->q_stats.nr_sbal_total += count;
+ if (count == QDIO_MAX_BUFFERS_MASK) {
+ q->q_stats.nr_sbals[7]++;
+ return;
+ }
+ while (count >>= 1)
+ pos++;
+ q->q_stats.nr_sbals[pos]++;
+}
+
static void announce_buffer_error(struct qdio_q *q, int count)
{
q->qdio_error |= QDIO_ERROR_SLSB_STATE;
@@ -487,16 +501,22 @@
q->first_to_check = add_buf(q->first_to_check, count);
if (atomic_sub(count, &q->nr_buf_used) == 0)
qperf_inc(q, inbound_queue_full);
+ if (q->irq_ptr->perf_stat_enabled)
+ account_sbals(q, count);
break;
case SLSB_P_INPUT_ERROR:
announce_buffer_error(q, count);
/* process the buffer, the upper layer will take care of it */
q->first_to_check = add_buf(q->first_to_check, count);
atomic_sub(count, &q->nr_buf_used);
+ if (q->irq_ptr->perf_stat_enabled)
+ account_sbals_error(q, count);
break;
case SLSB_CU_INPUT_EMPTY:
case SLSB_P_INPUT_NOT_INIT:
case SLSB_P_INPUT_ACK:
+ if (q->irq_ptr->perf_stat_enabled)
+ q->q_stats.nr_sbal_nop++;
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in nop");
break;
default:
@@ -643,15 +663,21 @@
atomic_sub(count, &q->nr_buf_used);
q->first_to_check = add_buf(q->first_to_check, count);
+ if (q->irq_ptr->perf_stat_enabled)
+ account_sbals(q, count);
break;
case SLSB_P_OUTPUT_ERROR:
announce_buffer_error(q, count);
/* process the buffer, the upper layer will take care of it */
q->first_to_check = add_buf(q->first_to_check, count);
atomic_sub(count, &q->nr_buf_used);
+ if (q->irq_ptr->perf_stat_enabled)
+ account_sbals_error(q, count);
break;
case SLSB_CU_OUTPUT_PRIMED:
/* the adapter has not fetched the output yet */
+ if (q->irq_ptr->perf_stat_enabled)
+ q->q_stats.nr_sbal_nop++;
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out primed:%1d", q->nr);
break;
case SLSB_P_OUTPUT_NOT_INIT:
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
== 3 of 3 ==
Date: Wed, Feb 24 2010 12:50 am
From: Martin Schwidefsky
From: Gerald Schaefer <gerald.schaefer@de.ibm.com>
This patch introduces a new function that checks the running status
of a cpu in a hypervisor. This status is not virtualized, so the check
is only correct if running in an LPAR. On acquiring a spinlock, if the
cpu holding the lock is scheduled by the hypervisor, we do a busy wait
on the lock. If it is not scheduled, we yield over to that cpu.
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---
arch/s390/include/asm/sigp.h | 40 ++++++++++++++----------------
arch/s390/include/asm/smp.h | 24 ++++++++++++++++++
arch/s390/lib/spinlock.c | 57 +++++++++++++++++++++++++++++--------------
3 files changed, 82 insertions(+), 39 deletions(-)
Index: quilt-2.6/arch/s390/include/asm/sigp.h
===================================================================
--- quilt-2.6.orig/arch/s390/include/asm/sigp.h 2010-02-24 09:28:13.000000000 +0100
+++ quilt-2.6/arch/s390/include/asm/sigp.h 2010-02-24 09:44:25.000000000 +0100
@@ -31,32 +31,31 @@
typedef enum
{
- sigp_unassigned=0x0,
- sigp_sense,
- sigp_external_call,
- sigp_emergency_signal,
- sigp_start,
- sigp_stop,
- sigp_restart,
- sigp_unassigned1,
- sigp_unassigned2,
- sigp_stop_and_store_status,
- sigp_unassigned3,
- sigp_initial_cpu_reset,
- sigp_cpu_reset,
- sigp_set_prefix,
- sigp_store_status_at_address,
- sigp_store_extended_status_at_address
+ sigp_sense = 1,
+ sigp_external_call = 2,
+ sigp_emergency_signal = 3,
+ sigp_start = 4,
+ sigp_stop = 5,
+ sigp_restart = 6,
+ sigp_stop_and_store_status = 9,
+ sigp_initial_cpu_reset = 11,
+ sigp_cpu_reset = 12,
+ sigp_set_prefix = 13,
+ sigp_store_status_at_address = 14,
+ sigp_store_extended_status_at_address = 15,
+ sigp_set_architecture = 18,
+ sigp_conditional_emergency_signal = 19,
+ sigp_sense_running = 21,
} sigp_order_code;
typedef __u32 sigp_status_word;
typedef enum
{
- sigp_order_code_accepted=0,
- sigp_status_stored,
- sigp_busy,
- sigp_not_operational
+ sigp_order_code_accepted = 0,
+ sigp_status_stored = 1,
+ sigp_busy = 2,
+ sigp_not_operational = 3,
} sigp_ccode;
@@ -70,7 +69,6 @@
ec_schedule=0,
ec_call_function,
ec_call_function_single,
- ec_bit_last
} ec_bit_sig;
/*
Index: quilt-2.6/arch/s390/include/asm/smp.h
===================================================================
--- quilt-2.6.orig/arch/s390/include/asm/smp.h 2010-02-24 09:44:24.000000000 +0100
+++ quilt-2.6/arch/s390/include/asm/smp.h 2010-02-24 09:44:25.000000000 +0100
@@ -36,6 +36,28 @@
int from, int to);
extern void smp_restart_cpu(void);
+/*
+ * returns 1 if (virtual) cpu is scheduled
+ * returns 0 otherwise
+ */
+static inline int smp_vcpu_scheduled(int cpu)
+{
+ __u32 status = 0;
+
+ switch (signal_processor_ps(&status, 0, cpu, sigp_sense_running)) {
+ case sigp_status_stored:
+ /* Check for running status */
+ if (status & 0x400)
+ return 0;
+ break;
+ case sigp_not_operational:
+ return 0;
+ default:
+ break;
+ }
+ return 1;
+}
+
#else /* CONFIG_SMP */
static inline void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
@@ -43,6 +65,8 @@
func(data);
}
+#define smp_vcpu_scheduled (1)
+
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home