From patchwork Fri Jan 9 16:19:17 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joerg Roedel X-Patchwork-Id: 17527 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 1126047534 for ; Sat, 10 Jan 2009 03:20:04 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752689AbZAIQT6 (ORCPT ); Fri, 9 Jan 2009 11:19:58 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752638AbZAIQT5 (ORCPT ); Fri, 9 Jan 2009 11:19:57 -0500 Received: from outbound-wa4.frontbridge.com ([216.32.181.16]:32121 "EHLO WA4EHSOBE006.bigfish.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752218AbZAIQTn (ORCPT ); Fri, 9 Jan 2009 11:19:43 -0500 Received: from mail170-wa4-R.bigfish.com (10.8.14.237) by WA4EHSOBE006.bigfish.com (10.8.40.26) with Microsoft SMTP Server id 8.1.291.1; Fri, 9 Jan 2009 16:19:43 +0000 Received: from mail170-wa4 (localhost.localdomain [127.0.0.1]) by mail170-wa4-R.bigfish.com (Postfix) with ESMTP id DFF641D030C; Fri, 9 Jan 2009 16:19:42 +0000 (UTC) X-BigFish: VPS3(zzzzzzz32i43j65h) X-Spam-TCS-SCL: 4:0 Received: by mail170-wa4 (MessageSwitch) id 1231517980323148_14699; Fri, 9 Jan 2009 16:19:40 +0000 (UCT) Received: from svlb1extmailp02.amd.com (unknown [139.95.251.11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail170-wa4.bigfish.com (Postfix) with ESMTP id 347DC1390053; Fri, 9 Jan 2009 16:19:40 +0000 (UTC) Received: from svlb1twp01.amd.com ([139.95.250.34]) by svlb1extmailp02.amd.com (Switch-3.2.7/Switch-3.2.7) with ESMTP id n09GJV4i004134; Fri, 9 Jan 2009 08:19:34 -0800 X-WSS-ID: 0KD7PCH-03-IWY-01 Received: from SSVLEXBH1.amd.com (ssvlexbh1.amd.com [139.95.53.182]) by svlb1twp01.amd.com (Tumbleweed MailGate 3.5.1) with ESMTP id 2DB63884942; Fri, 9 Jan 2009 08:19:29 -0800 (PST) Received: from SSVLEXMB1.amd.com ([139.95.53.181]) by SSVLEXBH1.amd.com with Microsoft SMTPSVC(6.0.3790.3959); Fri, 9 Jan 2009 08:19:35 -0800 Received: from SF36EXMB1.amd.com ([172.19.4.24]) by SSVLEXMB1.amd.com with Microsoft SMTPSVC(6.0.3790.3959); Fri, 9 Jan 2009 08:19:34 -0800 Received: from lemmy.localdomain ([165.204.77.20]) by SF36EXMB1.amd.com with Microsoft SMTPSVC(6.0.3790.3959); Fri, 9 Jan 2009 17:19:30 +0100 Received: by lemmy.localdomain (Postfix, from userid 41430) id 8E66253C46; Fri, 9 Jan 2009 17:19:30 +0100 (CET) From: Joerg Roedel To: linux-kernel@vger.kernel.org CC: mingo@redhat.com, dwmw2@infradead.org, fujita.tomonori@lab.ntt.co.jp, netdev@vger.kernel.org, iommu@lists.linux-foundation.org, Joerg Roedel Subject: [PATCH 03/16] dma-debug: add hash functions for dma_debug_entries Date: Fri, 9 Jan 2009 17:19:17 +0100 Message-ID: <1231517970-20288-4-git-send-email-joerg.roedel@amd.com> X-Mailer: git-send-email 1.5.6.4 In-Reply-To: <1231517970-20288-1-git-send-email-joerg.roedel@amd.com> References: <1231517970-20288-1-git-send-email-joerg.roedel@amd.com> X-OriginalArrivalTime: 09 Jan 2009 16:19:30.0605 (UTC) FILETIME=[0CF7E5D0:01C97276] MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Impact: implement necessary functions for the core hash Signed-off-by: Joerg Roedel --- lib/dma-debug.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 101 insertions(+), 0 deletions(-) diff --git a/lib/dma-debug.c b/lib/dma-debug.c index d04f8b6..74a0f36 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c @@ -18,9 +18,14 @@ */ #include +#include #include #include +#define HASH_SIZE 256 +#define HASH_FN_SHIFT 20 +#define HASH_FN_MASK 0xffULL + enum { dma_debug_single, dma_debug_sg, @@ -37,3 +42,99 @@ struct dma_debug_entry { int direction; }; +struct hash_bucket { + struct list_head list; + spinlock_t lock; +} ____cacheline_aligned; + +/* Hash list to save the allocated dma addresses */ +static struct hash_bucket dma_entry_hash[HASH_SIZE]; + +/* + * Hash related functions + * + * Every DMA-API request is saved into a struct dma_debug_entry. To + * have quick access to these structs they are stored into a hash. + */ +static int hash_fn(struct dma_debug_entry *entry) +{ + /* + * Hash function is based on the dma address. + * We use bits 20-27 here as the index into the hash + */ + return (entry->dev_addr >> HASH_FN_SHIFT) & HASH_FN_MASK; +} + +/* + * Request exclusive access to a hash bucket for a given dma_debug_entry. + */ +static struct hash_bucket *get_hash_bucket(struct dma_debug_entry *entry, + unsigned long *flags) +{ + int idx = hash_fn(entry); + unsigned long __flags; + + spin_lock_irqsave(&dma_entry_hash[idx].lock, __flags); + *flags = __flags; + return &dma_entry_hash[idx]; +} + +/* + * Give up exclusive access to the hash bucket + */ +static void put_hash_bucket(struct hash_bucket *bucket, + unsigned long *flags) +{ + unsigned long __flags = *flags; + + spin_unlock_irqrestore(&bucket->lock, __flags); +} + +/* + * Search a given entry in the hash bucket list + */ +static struct dma_debug_entry *hash_bucket_find(struct hash_bucket *bucket, + struct dma_debug_entry *ref) +{ + struct dma_debug_entry *entry; + + list_for_each_entry(entry, &bucket->list, list) { + if ((entry->dev_addr == ref->dev_addr) && + (entry->dev == ref->dev)) + return entry; + } + + return NULL; +} + +/* + * Add an entry to a hash bucket + */ +static void hash_bucket_add(struct hash_bucket *bucket, + struct dma_debug_entry *entry) +{ + list_add_tail(&entry->list, &bucket->list); +} + +/* + * Remove entry from a hash bucket list + */ +static void hash_bucket_del(struct dma_debug_entry *entry) +{ + list_del(&entry->list); +} + +/* + * Wrapper function for adding an entry to the hash. + * This function takes care of locking itself. + */ +static void add_dma_entry(struct dma_debug_entry *entry) +{ + struct hash_bucket *bucket; + unsigned long flags; + + bucket = get_hash_bucket(entry, &flags); + hash_bucket_add(bucket, entry); + put_hash_bucket(bucket, &flags); +} +