block: disable IRQs until data is written to relay
RFC PATCH 1/1 block: disable IRQs until data is written to relay
Hi,
Can you review this patch? I'm new to locking in the Linux kernel so I may be misssing something.
I think we must disable IRQs between relay_reserve and initializing the data; consider the following scenario where task 1 and task 2 runs on the same CPU:
task 1: trace_note_message task 2: interrupt userspace (blktrace) -------------------------- ----------------- -------------------- __trace_note_message read(relay) relay_reserve <blocks ...>
<interrupted: I/O completion>
__blk_add_trace
relay_reserve
<buffers switched,
wake user>
<reads uninitialized
trace_note_message>
<done><runs again>memcpy() - too late
Signature · 1 line
Carl Henrik
From 30fce97a2d7c02ba265eceed59592dbdc9c34f26 Mon Sep 17 00:00:00 2001
From: Carl Henrik Lunde <[email protected]>
Date: Fri, 30 May 2008 12:57:47 +0200
Subject: [PATCH] block: disable IRQs until data is written to relay channel
As we may run relay_reserve from interrupt context we must always disable IRQs. This is because a call to relay_reserve may expose previously written data to use space.
Updated new message code and an old but related comment.
--- block/blktrace.c | 10 ++++------ 1 files changed, 4 insertions(+), 6 deletions(-)
block/blktrace.c +4 -6
@@ -79,16 +79,17 @@ void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) {int n;va_list args; +unsigned long flags;char *buf; -preempt_disable (); +local_irq_save (flags); buf =per_cpu_ptr (bt->msg_data,smp_processor_id ());va_start (args, fmt); n =vscnprintf (buf,BLK_TN_MAX_MSG , fmt, args);va_end (args);trace_note (bt,0 ,BLK_TN_MESSAGE , buf, n); -preempt_enable (); +local_irq_restore (flags); }EXPORT_SYMBOL_GPL (__trace_note_message);
@@ -158,10 +159,7 @@ void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,/* * A word about the locking here - we disable interrupts to reserve * some space in the relay per-cpu buffer, to prevent an irq -* from coming in and stepping on our toes. Once reserved, it's -* enough to get preemption disabled to prevent read of this data -* before we are through filling it. get_cpu()/put_cpu() does this -* for us +* from coming in and stepping on our toes. */ local_irq_save (flags);
Signature · 1 line
1.5.4.3
Re: [RFC PATCH] block: disable IRQs until data is written to relay channel
Quoted 55 lines · Carl Henrik Lunde
Hi,
Can you review this patch? I'm new to locking in the Linux kernel so I may be misssing something.
I think we must disable IRQs between
relay_reserveand initializing the data; consider the following scenario where task 1 and task 2 runs on the same CPU:task 1: trace_note_message task 2: interrupt userspace (blktrace) -------------------------- ----------------- -------------------- __trace_note_message read(relay) relay_reserve <blocks ...><interrupted: I/O completion>
__blk_add_trace relay_reserve <buffers switched, wake user> <reads uninitialized trace_note_message> <done><runs again>
memcpy()- too lateSignature · 17 lines
Carl Henrik From 30fce97a2d7c02ba265eceed59592dbdc9c34f26 Mon Sep 17 00:00:00 2001 From: Carl Henrik Lunde <[email protected]> Date: Fri, 30 May 2008 12:57:47 +0200 Subject: [PATCH] block: disable IRQs until data is written to relay channel As we may run relay_reserve from interrupt context we must always disable IRQs. This is because a call to relay_reserve may expose previously written data to use space. Updated new message code and an old but related comment. Signed-off-by: Carl Henrik Lunde <[email protected]> --- block/blktrace.c | 10 ++++------ 1 files changed, 4 insertions(+), 6 deletions(-)block/blktrace.c +1
-0@@ -79,16 +79,17 @@ void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) {int n;va_list args; +unsigned long flags;char *buf;
block/blktrace.c void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) · line 92
Quoted 10 lines
block/blktrace.c +2
-2-preempt_disable (); +local_irq_save (flags); buf =per_cpu_ptr (bt->msg_data,smp_processor_id ());va_start (args, fmt); n =vscnprintf (buf,BLK_TN_MAX_MSG , fmt, args);va_end (args);trace_note (bt,0 ,BLK_TN_MESSAGE , buf, n); -preempt_enable (); +local_irq_restore (flags);
Good spotting, applied! Thanks.
Signature · 1 line
Jens Axboe
Re: [RFC PATCH] block: disable IRQs until data is written to relay channel
In reply to Carl Henrik LundeQuoted 63 lines · Jens Axboe
Quoted 62 lines · Carl Henrik Lunde
Hi,
Can you review this patch? I'm new to locking in the Linux kernel so I may be misssing something.
I think we must disable IRQs between
relay_reserveand initializing the data; consider the following scenario where task 1 and task 2 runs on the same CPU:task 1: trace_note_message task 2: interrupt userspace (blktrace) -------------------------- ----------------- -------------------- __trace_note_message read(relay) relay_reserve <blocks ...><interrupted: I/O completion>
__blk_add_trace relay_reserve <buffers switched, wake user> <reads uninitialized trace_note_message> <done><runs again>
memcpy()- too late--
Carl HenrikFrom
30fce97a2d7c02ba265eceed59592dbdc9c34f26Mon Sep 17 00:00:00 2001
From: Carl Henrik Lunde <[email protected]>
Date: Fri, 30 May 2008 12:57:47 +0200
Subject: [PATCH] block: disable IRQs until data is written to relay channelAs we may run
relay_reservefrom interrupt context we must always disable IRQs. This is because a call torelay_reservemay expose previously written data to use space.Updated new message code and an old but related comment.
Signed-off-by Carl Henrik Lunde <[email protected]>--- block/blktrace.c | 10 ++++------ 1 files changed, 4 insertions(+), 6 deletions(-)block/blktrace.c +2
-1@@ -79,16 +79,17 @@ void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) {int n;va_list args; +unsigned long flags;char *buf; -preempt_disable (); +local_irq_save (flags); buf =per_cpu_ptr (bt->msg_data,smp_processor_id ());va_start (args, fmt); n =vscnprintf (buf,BLK_TN_MAX_MSG , fmt, args);va_end (args);
Quoted 5 lines
block/blktrace.c void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) · line 92
Quoted 3 lines
block/blktrace.c +1
-1trace_note (bt,0 ,BLK_TN_MESSAGE , buf, n); -preempt_enable (); +local_irq_restore (flags);Good spotting, applied! Thanks.
Hmm, applied where?
Signature · 1 line
Carl Henrik
Re: [RFC PATCH] block: disable IRQs until data is written to relay channel
In reply to Carl Henrik LundeQuoted 64 lines · Carl Henrik Lunde
Quoted 63 lines · Jens Axboe
Quoted 62 lines · Carl Henrik Lunde
Hi,
Can you review this patch? I'm new to locking in the Linux kernel so I may be misssing something.
I think we must disable IRQs between
relay_reserveand initializing the data; consider the following scenario where task 1 and task 2 runs on the same CPU:task 1: trace_note_message task 2: interrupt userspace (blktrace) -------------------------- ----------------- -------------------- __trace_note_message read(relay) relay_reserve <blocks ...><interrupted: I/O completion>
__blk_add_trace relay_reserve <buffers switched, wake user> <reads uninitialized trace_note_message> <done><runs again>
memcpy()- too late--
Carl HenrikFrom
30fce97a2d7c02ba265eceed59592dbdc9c34f26Mon Sep 17 00:00:00 2001
From: Carl Henrik Lunde <[email protected]>
Date: Fri, 30 May 2008 12:57:47 +0200
Subject: [PATCH] block: disable IRQs until data is written to relay channelAs we may run
relay_reservefrom interrupt context we must always disable IRQs. This is because a call torelay_reservemay expose previously written data to use space.Updated new message code and an old but related comment.
Signed-off-by Carl Henrik Lunde <[email protected]>--- block/blktrace.c | 10 ++++------ 1 files changed, 4 insertions(+), 6 deletions(-)block/blktrace.c +2
-1@@ -79,16 +79,17 @@ void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) {int n;va_list args; +unsigned long flags;char *buf; -preempt_disable (); +local_irq_save (flags); buf =per_cpu_ptr (bt->msg_data,smp_processor_id ());va_start (args, fmt); n =vscnprintf (buf,BLK_TN_MAX_MSG , fmt, args);va_end (args);
Quoted 7 lines
Quoted 5 lines
block/blktrace.c void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) · line 92
Quoted 3 lines
block/blktrace.c +1
-1trace_note (bt,0 ,BLK_TN_MESSAGE , buf, n); -preempt_enable (); +local_irq_restore (flags);Good spotting, applied! Thanks.
Hmm, applied where?
Still local, I'll get it pushed out for 2.6.26 final for sure.
Signature · 1 line
Jens Axboe