From patchwork Tue Oct 30 18:42:53 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Behan Webster X-Patchwork-Id: 195584 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 27C702C0080 for ; Wed, 31 Oct 2012 05:42:55 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760276Ab2J3Smw (ORCPT ); Tue, 30 Oct 2012 14:42:52 -0400 Received: from mail-ia0-f174.google.com ([209.85.210.174]:58904 "EHLO mail-ia0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1760246Ab2J3Smu (ORCPT ); Tue, 30 Oct 2012 14:42:50 -0400 Received: by mail-ia0-f174.google.com with SMTP id y32so412759iag.19 for ; Tue, 30 Oct 2012 11:42:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=converseincode.com; s=google; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=jHzrlEURgIhOv4jbuRIv38MMc69NCk1CyYCp8hOaot0=; b=TztJSOO7FVC4cQx/XGUsssS2H50LrZuthHJxucvYuOa1/TixzpOlAxKQCUnhpz9rQ7 FIxNYi0VsQbcUd4eJbpo8NxeGfFmNBxXJdgblyMhRiBVMv3dyjtmz7EQHnXB6KnE9VjD 8ukBmqYTgEkCPwCr19atPb2pPkCXXr+Ay8GPw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=jHzrlEURgIhOv4jbuRIv38MMc69NCk1CyYCp8hOaot0=; b=HPql8L2wYbXiAgyA2a2LavrqWmP0P4Tgg6dVt35492xbOUR7MZOpjAKxjVe7qcIh4J OnVCq6cMMdeicdt6vZmX8AcxAmP5rUo95mbDWPpnNFvEWGTOJ82w2+91Tf6E4MOJgxKI h/mWrU3fAOsiPznrRS7R8LQpO3eq2JmNnEWWLl4gwRUrigYPwwlI5mjPMc7xNQVFs7TA RVK1f54F2g3/lSnZpRVsWbctxDBoTeTDJzdlXQbrDHcvQGRlDKrdTjRNi4AcxPK2ox1A Xyzk0ct2fWcK8GyE836axYP1Hvo2+k6yn7CVWDy9v57R9QvMOYkjpNVrKXgf77V+W8c/ ej9w== Received: by 10.50.160.138 with SMTP id xk10mr2439383igb.38.1351622570525; Tue, 30 Oct 2012 11:42:50 -0700 (PDT) Received: from GaldorVB.converseincode.com (216-58-123-56.cpe.distributel.net. [216.58.123.56]) by mx.google.com with ESMTPS id x7sm1139193igk.8.2012.10.30.11.42.49 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 30 Oct 2012 11:42:50 -0700 (PDT) Received: by GaldorVB.converseincode.com (Postfix, from userid 1000) id DB1B06509D; Tue, 30 Oct 2012 14:43:09 -0400 (EDT) From: Behan Webster To: davem@davemloft.net Cc: netfilter-devel@vger.kernel.org, linux-kernel@vger.kernel.org, Behan Webster Subject: [PATCH 1/2] Helper macros used for replacing the use of VLAIS Date: Tue, 30 Oct 2012 14:42:53 -0400 Message-Id: <1351622574-18421-2-git-send-email-behanw@converseincode.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1351622574-18421-1-git-send-email-behanw@converseincode.com> References: <1351622574-18421-1-git-send-email-behanw@converseincode.com> X-Gm-Message-State: ALoCoQlKSEsmHQ5Icc/MQSEu8jtWmoLx4lHy1efV8V22kbVRobSuRIyZ9GrUuu82cyjO6E/LsTJ2 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org The use of variable length arrays in structs (VLAIS) in the Linux Kernel code precludes the use of compilers which don't implement VLAIS (for instance the Clang compiler). This new header file contains macros which can be used to calculate the size and offset of variables in an allocated buffer of memory taking into account alignment issues. Signed-off-by: Behan Webster --- include/linux/valign.h | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 include/linux/valign.h diff --git a/include/linux/valign.h b/include/linux/valign.h new file mode 100644 index 0000000..b39381b --- /dev/null +++ b/include/linux/valign.h @@ -0,0 +1,87 @@ +/* + * Variable alignment macros used to break up a larger chunk of memory into + * smaller variables. Meant to be used to replace the use of Variable Length + * Arrays In Structures (VLAIS) + * + * Copyright (C) 2012 Behan Webster + */ + +#ifndef _VALIGN_H_ +#define _VALIGN_H_ + +/** + * truncalign() - Align a memory address by truncation + * @num: Address or size to align + * @padwidth: Number of byte upon which to align + * + * Truncate an address or size to a particular memory alignment. + * Used by truncalign(). + */ +#define truncalign(num, padwidth) ((long)(num) & ~((padwidth)-1)) + +/** + * padalign() - Align a memory address by padding + * @num: Address or size to align + * @padwidth: Number of byte upon which to align + * + * Pad out an address or size to a particular memory alignment + * Used by paddedsize() and paddedstart(). + */ +#define padalign(num, padwidth) \ + truncalign((long)(num) + ((padwidth)-1), padwidth) + +/** + * paddedsize() - Calculate the size of an chunk of aligned memory + * @offset: Unaligned offset to the start of the chunk size being calculated + * @num: The number of variables in the array of "type" (can be 1) + * @type: The type of variables in the array + * @nexttype: The type of the next variable in the large piece of memory + * + * Calculate the size that a variable (or array) will take as a part of a + * larger piece of memory. Takes into account a potentially unaligned offset + * into the larger piece of allocated memory, the alignment of the variable + * type, and the alignement of the type of the variable to be used after that. + * + * Example: size_t l = paddedsize(1, 2, short, int); + * + * The example above would give you a padded size of 6 bytes: 2x 16-bit shorts, + * starting at 2 bytes into the buffer (the offset of 1 byte being padded out + * to 2 bytes) followed by 2 bytes of padding so that the next type (a 32-bit + * int) would be 32-bit aligned. looking like this: + * + * 0: O.SS SS.. iiii + * \-----/ <-- 2 shorts + 2 bytes of padding = size of 6 bytes + * + * O = The offset + * . = Padding bytes + * S = 2 shorts + * i = int which will theoretically be next + */ +#define paddedsize(offset, num, type, nexttype) (padalign((offset) \ + + (num) * sizeof(type), __alignof__(nexttype)) - (offset)) + +/** + * paddedstart() - Calculate the start of a chunk of aligned memory + * @ptr: Pointer from which to calculate the start of the chunk + * @offset: Offset from the ptr to the start of the chunk being calculated + * @type: The type of variable in the chunk of memory + * + * Calculate the start address of a variable based on the offset from an + * address, aligned based on the type of the variable specified. + * + * Example: char *data = kmalloc(size, GFP_KERNEL); + * long *var = paddedstart(data, 12, long); + * + * The example above on a 64-bit machine would return the equivalent of + * &buffer[16] since a long needs to be 8 byte aligned. + * + * 0: OOOO OOOO OOOO .... LLLL LLLL + * ^ <-- The start address of the long + * O = The offset + * . = Padding bytes + * L = The long + */ +#define paddedstart(ptr, offset, type) \ + (type *)padalign((long)(ptr)+(offset), __alignof__(type)) + +#endif