From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760206AbZDQJ3b (ORCPT ); Fri, 17 Apr 2009 05:29:31 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1758460AbZDQJ3V (ORCPT ); Fri, 17 Apr 2009 05:29:21 -0400 Received: from casper.infradead.org ([85.118.1.10]:37123 "EHLO casper.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758104AbZDQJ3U (ORCPT ); Fri, 17 Apr 2009 05:29:20 -0400 Subject: Re: [PATCH 1/2 v2] tracing/events: provide string with undefined size support From: Peter Zijlstra To: =?ISO-8859-1?Q?Fr=E9d=E9ric?= Weisbecker Cc: Ingo Molnar , Steven Rostedt , Zhaolei , Tom Zanussi , Li Zefan , KOSAKI Motohiro , LKML In-Reply-To: References: <1239912047-6282-1-git-send-email-fweisbec@gmail.com> <1239912812.23397.3432.camel@laptop> <1239949360.23397.4065.camel@laptop> Content-Type: text/plain; charset="UTF-8" Date: Fri, 17 Apr 2009 11:29:08 +0200 Message-Id: <1239960548.23397.4282.camel@laptop> Mime-Version: 1.0 X-Mailer: Evolution 2.26.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, 2009-04-17 at 10:59 +0200, Frédéric Weisbecker wrote: > struct foo { > field1; > field2; > ... > }; > > struct foo *f; > > event = ring_buffer_lock_reserve(sizeof(*f), ...); > f = ring_buffer_event_data(event); > > I can't use a kmalloc here. We are tracing a random event which can happen > at a random frequency, random context, etc... Can't you add a bit to that ring_buffer_lock_reserve() thing? The thing I do for perf_counters is I first iterate all the output, then make the reserve large enough to fit all the output in, then copy the bits into the output buffer. The result is that the output cannot be interpreted as a fixed offset struct, but that's not much of an issue anyway. Another possibility is using relative pointers for strings that point beyond the tail of the fixed offset struct. So something like: __field(int, foo); __string(bar); __field(int, foo2); __string(bar2); __field(int, foo3); would look like: struct plop { int foo; char *bar; int foo2; char *bar2; int foo3; char data[0]; } and you'd do something like: size = sizeof(struct plop); size += strlen(bar) + 1; size += strlen(bar2) + 1; event = ring_buffer_lock_reserve(size); offset = sizeof(struct plop); my_plop.bar = (char *)offset; offset += strlen(bar) + 1; my_plop.bar2 = (char *)offset; memcpy(&event, &my_plop, sizeof(struct plop)); memcpy(&event + my_plop.bar, bar, strlen(bar)+1); memcpy(&event + my_plop.bar2, bar2, strlen(bar2)+1); ring_buffer_unlock(); Then on reading, you'd get a variable sized entry, with a fixed size fixed offset struct, that contains relative offset character pointers.