From patchwork Tue Jan 12 19:10:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gregory CLEMENT X-Patchwork-Id: 8020571 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D2D819F3F6 for ; Tue, 12 Jan 2016 19:16:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DB42C203F4 for ; Tue, 12 Jan 2016 19:16:22 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EE26520125 for ; Tue, 12 Jan 2016 19:16:21 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aJ4Os-0000L0-Mt; Tue, 12 Jan 2016 19:14:38 +0000 Received: from down.free-electrons.com ([37.187.137.238] helo=mail.free-electrons.com) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aJ4Lx-00064x-Bj for linux-arm-kernel@lists.infradead.org; Tue, 12 Jan 2016 19:11:45 +0000 Received: by mail.free-electrons.com (Postfix, from userid 110) id 17649294; Tue, 12 Jan 2016 20:11:19 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from localhost (81-67-231-93.rev.numericable.fr [81.67.231.93]) by mail.free-electrons.com (Postfix) with ESMTPSA id 1DF132C0; Tue, 12 Jan 2016 20:10:44 +0100 (CET) From: Gregory CLEMENT To: "David S. Miller" , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Thomas Petazzoni , Florian Fainelli Subject: [PATCH net-next 09/10] net: Add a hardware buffer management helper API Date: Tue, 12 Jan 2016 20:10:33 +0100 Message-Id: <1452625834-22166-10-git-send-email-gregory.clement@free-electrons.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1452625834-22166-1-git-send-email-gregory.clement@free-electrons.com> References: <1452625834-22166-1-git-send-email-gregory.clement@free-electrons.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160112_111138_235692_F08D2CAD X-CRM114-Status: GOOD ( 20.49 ) X-Spam-Score: -1.9 (-) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lior Amsalem , Andrew Lunn , Russell King - ARM Linux , Jason Cooper , Arnd Bergmann , Boris BREZILLON , Simon Guinot , Nadav Haklai , Ezequiel Garcia , Gregory CLEMENT , Maxime Ripard , Marcin Wojtas , Willy Tarreau , linux-arm-kernel@lists.infradead.org, Sebastian Hesselbarth MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This basic implementation allows to share code between driver using hardware buffer management. As the code is hardware agnostic, there is few helpers, most of the optimization brought by the an HW BM has to be done at driver level. Signed-off-by: Gregory CLEMENT --- include/net/hwbm.h | 19 +++++++++++++ net/core/Makefile | 2 +- net/core/hwbm.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 include/net/hwbm.h create mode 100644 net/core/hwbm.c diff --git a/include/net/hwbm.h b/include/net/hwbm.h new file mode 100644 index 000000000000..898ccd2fb58d --- /dev/null +++ b/include/net/hwbm.h @@ -0,0 +1,19 @@ +#ifndef _HWBM_H +#define _HWBM_H + +struct hwbm_pool { + /* Size of the buffers managed */ + int size; + /* Number of buffers currently used by this pool */ + int buf_num; + /* constructor called during alocation */ + int (*construct)(struct hwbm_pool *bm_pool, void *buf); + /* private data */ + void *priv; +}; + +void hwbm_buf_free(struct hwbm_pool *bm_pool, void *buf); +int hwbm_pool_refill(struct hwbm_pool *bm_pool); +int hwbm_pool_add(struct hwbm_pool *bm_pool, int buf_num); + +#endif /* _HWBM_H */ diff --git a/net/core/Makefile b/net/core/Makefile index 0b835de04de3..df81bf11f072 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -9,7 +9,7 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o obj-y += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \ neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ - sock_diag.o dev_ioctl.o tso.o sock_reuseport.o + sock_diag.o dev_ioctl.o tso.o sock_reuseport.o hwbm.o obj-$(CONFIG_XFRM) += flow.o obj-y += net-sysfs.o diff --git a/net/core/hwbm.c b/net/core/hwbm.c new file mode 100644 index 000000000000..d5d40d63cb34 --- /dev/null +++ b/net/core/hwbm.c @@ -0,0 +1,78 @@ +/* Support for hardware buffer manager. + * + * Copyright (C) 2016 Marvell + * + * Gregory CLEMENT + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include + +void hwbm_buf_free(struct hwbm_pool *bm_pool, void *buf) +{ + if (likely(bm_pool->size <= PAGE_SIZE)) + skb_free_frag(buf); + else + kfree(buf); +} +EXPORT_SYMBOL_GPL(hwbm_buf_free); + +/* Refill processing for HW buffer management */ +int hwbm_pool_refill(struct hwbm_pool *bm_pool) +{ + void *buf; + int frag_size = bm_pool->size; + + if (likely(frag_size <= PAGE_SIZE)) + buf = netdev_alloc_frag(frag_size); + else + buf = kmalloc(frag_size, GFP_ATOMIC); + + if (!buf) + return -ENOMEM; + + if (bm_pool->construct) + if (bm_pool->construct(bm_pool, buf)) { + hwbm_buf_free(bm_pool, buf); + return -ENOMEM; + } + + return 0; +} +EXPORT_SYMBOL_GPL(hwbm_pool_refill); + +int hwbm_pool_add(struct hwbm_pool *bm_pool, int buf_num) +{ + int err, i; + + if (bm_pool->buf_num == bm_pool->size) { + pr_debug("pool already filled\n"); + return bm_pool->buf_num; + } + + if (buf_num + bm_pool->buf_num > bm_pool->size) { + pr_debug("cannot allocate %d buffers for pool\n", + buf_num); + return 0; + } + + for (i = 0; i < buf_num; i++) { + err = hwbm_pool_refill(bm_pool); + if (err < 0) + break; + } + + /* Update BM driver with number of buffers added to pool */ + bm_pool->buf_num += i; + + pr_debug("hwpm pool: %d of %d buffers added\n", i, buf_num); + + return i; +} +EXPORT_SYMBOL_GPL(hwbm_pool_add);