From patchwork Wed Feb 23 23:04:18 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stephen hemminger X-Patchwork-Id: 84268 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.180.67]) by ozlabs.org (Postfix) with ESMTP id BF0F2B7291 for ; Thu, 24 Feb 2011 10:08:21 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755217Ab1BWXIJ (ORCPT ); Wed, 23 Feb 2011 18:08:09 -0500 Received: from suva.vyatta.com ([76.74.103.44]:47471 "EHLO suva.vyatta.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754673Ab1BWXHt (ORCPT ); Wed, 23 Feb 2011 18:07:49 -0500 Received: from suva.vyatta.com (suva [127.0.0.1]) by suva.vyatta.com (8.13.7/8.13.7) with ESMTP id p1NN7ZxA003719; Wed, 23 Feb 2011 15:07:35 -0800 Received: (from shemminger@localhost) by suva.vyatta.com (8.13.7/8.13.7/Submit) id p1NN7ZI1003718; Wed, 23 Feb 2011 15:07:35 -0800 Message-Id: <20110223230534.173432150@vyatta.com> User-Agent: quilt/0.48-1 Date: Wed, 23 Feb 2011 15:04:18 -0800 From: Stephen Hemminger To: "David S. Miller" Cc: netdev@vger.kernel.org Subject: [PATCH net-next 2/6] netem: use vmalloc for distribution table References: <20110223230416.532009518@vyatta.com> Content-Disposition: inline; filename=netem-vmalloc.patch Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The netem probability table can be large (up to 64K bytes) which may be too large to allocate in one contiguous chunk. Signed-off-by: Stephen Hemminger --- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- a/net/sched/sch_netem.c 2011-02-23 14:43:27.000000000 -0800 +++ b/net/sched/sch_netem.c 2011-02-23 14:49:07.228646202 -0800 @@ -308,6 +308,16 @@ static void netem_reset(struct Qdisc *sc qdisc_watchdog_cancel(&q->watchdog); } +static void dist_free(struct disttable *d) +{ + if (d) { + if (is_vmalloc_addr(d)) + vfree(d); + else + kfree(d); + } +} + /* * Distribution data is a variable size payload containing * signed 16 bit values. @@ -315,16 +325,20 @@ static void netem_reset(struct Qdisc *sc static int get_dist_table(struct Qdisc *sch, const struct nlattr *attr) { struct netem_sched_data *q = qdisc_priv(sch); - unsigned long n = nla_len(attr)/sizeof(__s16); + size_t n = nla_len(attr)/sizeof(__s16); const __s16 *data = nla_data(attr); spinlock_t *root_lock; struct disttable *d; int i; + size_t s; if (n > 65536) return -EINVAL; - d = kmalloc(sizeof(*d) + n*sizeof(d->table[0]), GFP_KERNEL); + s = sizeof(struct disttable) + n * sizeof(s16); + d = kmalloc(s, GFP_KERNEL); + if (!d) + d = vmalloc(s); if (!d) return -ENOMEM; @@ -335,7 +349,7 @@ static int get_dist_table(struct Qdisc * root_lock = qdisc_root_sleeping_lock(sch); spin_lock_bh(root_lock); - kfree(q->delay_dist); + dist_free(q->delay_dist); q->delay_dist = d; spin_unlock_bh(root_lock); return 0; @@ -556,7 +570,7 @@ static void netem_destroy(struct Qdisc * qdisc_watchdog_cancel(&q->watchdog); qdisc_destroy(q->qdisc); - kfree(q->delay_dist); + dist_free(q->delay_dist); } static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)