Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S261439AbUFHN1h (ORCPT ); Tue, 8 Jun 2004 09:27:37 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S265203AbUFHN1g (ORCPT ); Tue, 8 Jun 2004 09:27:36 -0400 Received: from cantor.suse.de ([195.135.220.2]:18576 "EHLO Cantor.suse.de") by vger.kernel.org with ESMTP id S261439AbUFHN1c (ORCPT ); Tue, 8 Jun 2004 09:27:32 -0400 Date: Tue, 08 Jun 2004 15:27:30 +0200 Message-ID: From: Takashi Iwai To: Russell King Cc: Jeff Garzik , linux-kernel@vger.kernel.org, viro@parcelfarce.linux.theplanet.co.uk, perex@suse.cz, torvalds@osdl.org Subject: Re: [RFC] ASLA design, depth of code review and lack thereof In-Reply-To: <20040607151806.C28526@flint.arm.linux.org.uk> References: <20040604230819.GR12308@parcelfarce.linux.theplanet.co.uk> <40C107D2.9030301@pobox.com> <40C471FC.3000802@pobox.com> User-Agent: Wanderlust/2.10.1 (Watching The Wheels) SEMI/1.14.5 (Awara-Onsen) FLIM/1.14.5 (Demachiyanagi) APEL/10.6 MULE XEmacs/21.4 (patch 13) (Rational FORTRAN) (i386-suse-linux) MIME-Version: 1.0 (generated by SEMI 1.14.5 - "Awara-Onsen") Content-Type: text/plain; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3903 Lines: 109 At Mon, 7 Jun 2004 15:18:06 +0100, Russell King wrote: > > On Mon, Jun 07, 2004 at 03:57:51PM +0200, Takashi Iwai wrote: > > They're nice but they don't provide "cast checking", no? > > The main purpose of the magic_* stuffs in ALSA is to check the cast of > > the void pointer back to the original data type, which the compiler > > can't check. > > > > Maybe we can implement only this "magic" check separetly and get rid > > of allocation checks, but I'm not sure whether it's worthy to do > > that. > > I must ask the question: why is ALSA such a special case that it > needs this level of "magic" checking, when the rest of the kernel > has happily used void pointers to carry driver specific data around > for the last 10 years without serious incident or any major debugging > problems? Sure, it isn't always needed for the matured drivers. The magic check is a (kind of) debugging stuff, as you can see even in linux/spinlock.h. The ugliness in ALSA's implementation is that it isn't transparent but forces to use some unusual macros. From the viewpoint of code readability, I'm willing to get rid of them, too. But this indeed can help sometimes to catch silly bugs, especially in the initial development phase. That's the reason I hesitate to remove it completely. > As long as objects are cleanly defined, and it is obvious what these > private driver specific pointers are for, then this "magic" become > unnecessary. Take a look at the driver model for instance. > > For instance, dev_set_drvdata() and dev_get_drvdata() provide access > to a clearly defined void pointer for drivers to use. It is clear > that a device driver uses it to place its private data structure > there, and it is the only code which should be accessing that. That's a good point. Having the interface for accessing such a private data is better. However, the obtained data is still void pointer. Suppose that you have a driver spreaded over several source files and you change the data type of this private data. A careless programmer like me might forget to change a part in another file. The driver still compiles and runs fine unless it hits casually the unchanged part and results in memory corruption. That's a silly scenario, but I believe the dynamic cast check is usefull for catching such a bug easily. That's why we see similar magic checks here and there. The question is how clean it's represented. I'm thinking of a simpler way, i.e. introducing macros something like: #ifdef DEBUG #define MAGIC_NUMBER unsigned int __magic_number; #define SET_MAGIC(rec,magic) ((rec)->__magic_number = (magic)) #define CHECK_MAGIC(rec,magic,action) do { \ if ((rec) == NULL || (rec)->__magic_number != (magic)) {\ SOME_ERROR(); action; \ } } while (0) #else #define MAGIC_NUMBER #define SET_MAGIC(rec,magic) #define CHEC_MAGIC(rec,magic,action) #endif struct foo { ... MAGIC_NUMBER; }; #define MY_MAGIC 0xabcd1234 static void allocate() { struct foo *data = kmalloc(sizeof(*data)); SET_MAGIC(data, MY_MAGIC); ... } static int handler(void *private_data) { struct foo *data = private_data; CHECK_MAGIC(data, MY_MAGIC, return -EINVAL); ... } In this case, we can simply remove *_MAGIC from the final version (if wanted), while the current ALSA magic implementation can't be removed simply. > I guess though that the problem area for ALSA is the way the snd_pcm_t > private_data member magically appears in the snd_pcm_substream_t > private_data member behind the drivers back, so it's unclear who > actually owns the data in the private_data members. Well, this is not the case. Usually a driver uses only one of them. Takashi - 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/