From patchwork Thu Nov 17 20:25:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luc Van Oostenryck X-Patchwork-Id: 9435305 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E7E2860471 for ; Thu, 17 Nov 2016 20:25:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D7043296CA for ; Thu, 17 Nov 2016 20:25:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C82E4296B4; Thu, 17 Nov 2016 20:25:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4C614296B4 for ; Thu, 17 Nov 2016 20:25:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751233AbcKQUZ3 (ORCPT ); Thu, 17 Nov 2016 15:25:29 -0500 Received: from mail-wm0-f65.google.com ([74.125.82.65]:34835 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751091AbcKQUZ3 (ORCPT ); Thu, 17 Nov 2016 15:25:29 -0500 Received: by mail-wm0-f65.google.com with SMTP id a20so24780669wme.2 for ; Thu, 17 Nov 2016 12:25:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=7h0EFYsedFyxf4y8Ubn1YuP1N925ORetuXoGIgKA0ww=; b=mzYrrb2NWfY4PqpPvDlQhCtrtYlYMNqPqE8EC/szBXWOMJEOznA4XE5hW0YT+gpNuF Fb/0mvt0OQ2iERKxrVT9O3gmFhHppXjNl5vPcwXdUsLfRQNBy/zjkaTabXNpbnv41N9z nSH+ssJDy92yGSif6Agjg7rfhX45ZE756ZTbQjr5KoyYjfKdZWCAX1YVzYnIn9ainlBF vBJxhWDfCk7nmTMymt4FDWcZDRZ29keICEOqIuM8qRxV9F0jNrk5Yjn5R40r6D3hVv// VclWAMYfDB6zIvbnv7VHgf89Kf45VePNL3EXEZA97GLDUnMykef0+cXF2a7ADgMjL1MS cepQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=7h0EFYsedFyxf4y8Ubn1YuP1N925ORetuXoGIgKA0ww=; b=VN7oMpmFhDmZzwhZk7G8faueW+C3BcRzWlsW0+XPm7wdkqUl6fAyB9BylHIWLpZM2g d7hfu07BEUw/x1EGLnt7zLShZRYx3KFjer0LU1b12RyEVqYtxDNYQIG3urJwrhxn9Elm 7tio12r/VYWamLZPce0jLWypFtv7+LX+0xQuSjq6/A7okcD5uQ9PQmfK5H7STYWhDc8G MIYDhSMWEp6fSrzKm8qaZxIWpb9MskjUECKum1HbI2I5PJ8GgbWd6/R+VIpjXIUUIWxL KrlU3g+ojKoRPRbRYjLyNUuwIPTeJBW0FSfvjL8uVU0Vs8NA5UWeygw8hteqSvKHwS+6 jspA== X-Gm-Message-State: AKaTC00YRSGuXWWfIgn1lgxyqkT3z23/TDIBmepcaUOdrQSdjS7YOYpWSo0/ZrB5i8KzDQ== X-Received: by 10.28.57.193 with SMTP id g184mr6106543wma.122.1479414327443; Thu, 17 Nov 2016 12:25:27 -0800 (PST) Received: from macpro.local ([2a02:a03f:845:bb00:a95b:d315:b100:4b73]) by smtp.gmail.com with ESMTPSA id bj1sm5083480wjc.17.2016.11.17.12.25.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 17 Nov 2016 12:25:26 -0800 (PST) Date: Thu, 17 Nov 2016 21:25:24 +0100 From: Luc Van Oostenryck To: Linus Torvalds Cc: Sparse Mailing-list , Christopher Li , Dan Carpenter Subject: Re: [PATCH 0/2] be more generous with ptrlist repacking Message-ID: <20161117202523.GA35194@macpro.local> References: <20161117172559.29417-1-luc.vanoostenryck@gmail.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.6.0 (2016-04-01) Sender: linux-sparse-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sparse@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Thu, Nov 17, 2016 at 09:40:20AM -0800, Linus Torvalds wrote: > On Thu, Nov 17, 2016 at 9:25 AM, Luc Van Oostenryck > wrote: > > The macros that do the ptrlist walking don't handle empty blocks. > > Actually, most of the_do_ handle empty blocks. In particular, the > normal FOR_EACH_PTR() case should handle it just fine. Yes, indeed. > The exception is, I think: > > - first_ptr_list/last_ptr_list > > - DO_PREPARE/DO_RESET ... > I suspect they should be fairly easy to update to just walk the list > until they hit a non-empty case (like DO_NEXT() already does, for > example). > > Linus > -- Would something like the following be fine? From bf7f856f95a71b931559a17c0f5144cd3a3875b5 Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Thu, 17 Nov 2016 20:59:18 +0100 Subject: [PATCH] make ptrlist walking against robust against empty blocks Not all macros or function involved in the ptrlist walking can handle a ptrlist containing some empty blocks. Fix this by: - add the proper check & looping to first & last_ptr_list(). - add a safe version of PTR_ENTRY doing the needed check & looping. - use this safe version for DO_PREPARE() & DO_RESET() Suggested-by: Linus Torvalds CC: Dan Carpenter Signed-off-by: Luc Van Oostenryck Tested-by: Luc Van Oostenryck --- I've quickly checked it on the testsuite (and it seems to pass ;). I'll validate this more thoroughly but I won't be able to do this just now. --- ptrlist.h | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/ptrlist.h b/ptrlist.h index 61e159fd..d09be2f5 100644 --- a/ptrlist.h +++ b/ptrlist.h @@ -67,28 +67,51 @@ extern int linearize_ptr_list(struct ptr_list *, void **, int); static inline void *first_ptr_list(struct ptr_list *list) { + struct ptr_list *head = list; + if (!list) return NULL; + + while (list->nr == 0) { + list = list->next; + if (list == head) + return NULL; + } return PTR_ENTRY(list, 0); } static inline void *last_ptr_list(struct ptr_list *list) { + struct ptr_list *head = list; if (!list) return NULL; list = list->prev; + while (list->nr == 0) { + if (list == head) + return NULL; + list = list->prev; + } return PTR_ENTRY(list, list->nr-1); } +#define PTR_DEREF(__head, idx, PTR_ENTRY) ({ \ + struct ptr_list *__list = __head; \ + while (__list && __list->nr == 0) { \ + __list = __list->next; \ + if (__list == __head) \ + __list = NULL; \ + } \ + __list ? PTR_ENTRY(__list, idx) : NULL; \ +}) + #define DO_PREPARE(head, ptr, __head, __list, __nr, PTR_ENTRY) \ do { \ struct ptr_list *__head = (struct ptr_list *) (head); \ struct ptr_list *__list = __head; \ int __nr = 0; \ CHECK_TYPE(head,ptr); \ - if (__head) ptr = PTR_ENTRY(__head, 0); \ - else ptr = NULL + ptr = PTR_DEREF(__head, 0, PTR_ENTRY); \ #define DO_NEXT(ptr, __head, __list, __nr, PTR_ENTRY) \ if (ptr) { \ @@ -110,7 +133,7 @@ static inline void *last_ptr_list(struct ptr_list *list) do { \ __nr = 0; \ __list = __head; \ - if (__head) ptr = PTR_ENTRY(__head, 0); \ + if (__head) ptr = PTR_DEREF(__head, 0, PTR_ENTRY); \ } while (0) #define DO_FINISH(ptr, __head, __list, __nr) \