Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755751AbcCCCOE (ORCPT ); Wed, 2 Mar 2016 21:14:04 -0500 Received: from szxga03-in.huawei.com ([119.145.14.66]:31842 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751062AbcCCCOC (ORCPT ); Wed, 2 Mar 2016 21:14:02 -0500 Subject: Re: [PATCH 10/46] perf core: Introduce new ioctl options to pause and resume ring buffer To: Peter Zijlstra References: <1456479154-136027-1-git-send-email-wangnan0@huawei.com> <1456479154-136027-11-git-send-email-wangnan0@huawei.com> <20160229153929.GD32719@kernel.org> CC: Arnaldo Carvalho de Melo , Alexei Starovoitov , Arnaldo Carvalho de Melo , Jiri Olsa , Li Zefan , , , He Kuang , Brendan Gregg , Masami Hiramatsu , Namhyung Kim From: "Wangnan (F)" Message-ID: <56D79B5E.4030609@huawei.com> Date: Thu, 3 Mar 2016 10:03:10 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.5.0 MIME-Version: 1.0 In-Reply-To: <20160229153929.GD32719@kernel.org> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [10.111.66.109] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020205.56D79BC9.006B,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2013-05-26 15:14:31, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 408073380e6271fb2665919672160ad1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4673 Lines: 137 Hi Peter, Patch 10/46 to 14/46 were sent separately to you and modified follow your suggestion. Do you have further comment on it? Thank you. On 2016/2/29 23:39, Arnaldo Carvalho de Melo wrote: > Em Fri, Feb 26, 2016 at 09:31:58AM +0000, Wang Nan escreveu: >> Add new ioctl() to pause/resume ring-buffer output. >> >> In some situations we want to read from ring buffer only when we >> ensure nothing can write to the ring buffer during reading. Without >> this patch we have to turn off all events attached to this ring buffer >> to achieve this. >> >> This patch is for supporting overwrite ring buffer. Following >> commits will introduce new methods support reading from overwrite ring >> buffer. Before reading caller must ensure the ring buffer is frozen, or >> the reading is unreliable. > Peter, have you have the chance too look at this and the other kernel > bits in this kit? > > - Arnaldo > >> Signed-off-by: Wang Nan >> Cc: He Kuang >> Cc: Alexei Starovoitov >> Cc: Arnaldo Carvalho de Melo >> Cc: Brendan Gregg >> Cc: Jiri Olsa >> Cc: Masami Hiramatsu >> Cc: Namhyung Kim >> Cc: Peter Zijlstra >> Cc: Zefan Li >> Cc: pi3orama@163.com >> --- >> include/uapi/linux/perf_event.h | 1 + >> kernel/events/core.c | 13 +++++++++++++ >> kernel/events/internal.h | 11 +++++++++++ >> kernel/events/ring_buffer.c | 7 ++++++- >> 4 files changed, 31 insertions(+), 1 deletion(-) >> >> diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h >> index 1afe962..a3c1903 100644 >> --- a/include/uapi/linux/perf_event.h >> +++ b/include/uapi/linux/perf_event.h >> @@ -401,6 +401,7 @@ struct perf_event_attr { >> #define PERF_EVENT_IOC_SET_FILTER _IOW('$', 6, char *) >> #define PERF_EVENT_IOC_ID _IOR('$', 7, __u64 *) >> #define PERF_EVENT_IOC_SET_BPF _IOW('$', 8, __u32) >> +#define PERF_EVENT_IOC_PAUSE_OUTPUT _IOW('$', 9, __u32) >> >> enum perf_event_ioc_flags { >> PERF_IOC_FLAG_GROUP = 1U << 0, >> diff --git a/kernel/events/core.c b/kernel/events/core.c >> index 94c47e3..a7075ae 100644 >> --- a/kernel/events/core.c >> +++ b/kernel/events/core.c >> @@ -4231,6 +4231,19 @@ static long _perf_ioctl(struct perf_event *event, unsigned int cmd, unsigned lon >> case PERF_EVENT_IOC_SET_BPF: >> return perf_event_set_bpf_prog(event, arg); >> >> + case PERF_EVENT_IOC_PAUSE_OUTPUT: { >> + struct ring_buffer *rb; >> + >> + rcu_read_lock(); >> + rb = rcu_dereference(event->rb); >> + if (!event->rb) { >> + rcu_read_unlock(); >> + return -EINVAL; >> + } >> + rb_toggle_paused(rb, !!arg); >> + rcu_read_unlock(); >> + return 0; >> + } >> default: >> return -ENOTTY; >> } >> diff --git a/kernel/events/internal.h b/kernel/events/internal.h >> index 2bbad9c..6a93d1b 100644 >> --- a/kernel/events/internal.h >> +++ b/kernel/events/internal.h >> @@ -18,6 +18,7 @@ struct ring_buffer { >> #endif >> int nr_pages; /* nr of data pages */ >> int overwrite; /* can overwrite itself */ >> + int paused; /* can write into ring buffer */ >> >> atomic_t poll; /* POLL_ for wakeups */ >> >> @@ -65,6 +66,16 @@ static inline void rb_free_rcu(struct rcu_head *rcu_head) >> rb_free(rb); >> } >> >> +static inline void >> +rb_toggle_paused(struct ring_buffer *rb, >> + bool pause) >> +{ >> + if (!pause && rb->nr_pages) >> + rb->paused = 0; >> + else >> + rb->paused = 1; >> +} >> + >> extern struct ring_buffer * >> rb_alloc(int nr_pages, long watermark, int cpu, int flags); >> extern void perf_event_wakeup(struct perf_event *event); >> diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c >> index 1faad2c..22e1a47 100644 >> --- a/kernel/events/ring_buffer.c >> +++ b/kernel/events/ring_buffer.c >> @@ -125,8 +125,11 @@ int perf_output_begin(struct perf_output_handle *handle, >> if (unlikely(!rb)) >> goto out; >> >> - if (unlikely(!rb->nr_pages)) >> + if (unlikely(rb->paused)) { >> + if (rb->nr_pages) >> + local_inc(&rb->lost); >> goto out; >> + } >> >> handle->rb = rb; >> handle->event = event; >> @@ -244,6 +247,8 @@ ring_buffer_init(struct ring_buffer *rb, long watermark, int flags) >> INIT_LIST_HEAD(&rb->event_list); >> spin_lock_init(&rb->event_lock); >> init_irq_work(&rb->irq_work, rb_irq_work); >> + >> + rb->paused = rb->nr_pages ? 0 : 1; >> } >> >> static void ring_buffer_put_async(struct ring_buffer *rb) >> -- >> 1.8.3.4