From patchwork Thu Aug 22 14:13:26 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Richter X-Patchwork-Id: 19417 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f198.google.com (mail-qc0-f198.google.com [209.85.216.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id B6BB6248E6 for ; Thu, 22 Aug 2013 14:14:55 +0000 (UTC) Received: by mail-qc0-f198.google.com with SMTP id a11sf1612879qcx.9 for ; Thu, 22 Aug 2013 07:14:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:delivered-to:sender:from:to:cc:subject:date:message-id :in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=SC8uAIF6Z00RjgDK0+cI2cmYZ34ViAlmgyGeVrDhyP8=; b=MLXvwDvOB9SzUgV88JIPQnt3ytYpVsQRme9jF6LgfDEjtH/hZ1vVbBn4a8Xao2sYQo ueAkykuKM8K9wSrkr7OEF9/yoZQN+OPlvHG7gnWjCUKm76znILFjDqRmTYPMyG0Ry9jk nXYg92r4n0vDMlcJctjhA9ey2O50ZLO5uw7prWk1/KAZl3KGt0y15g6BkOBocJt/DKFf +92wL6nbNx4rIwuQx9/DrOF54yy4vnmjXjnRV/NWfPN904YQsEUwX8bfyrssNjPxDWZc V2yVK2VIz+Zje0VGyS/UZ+c1wYOLYtaaZdUf5gTwSgaXKJIlp2oidfbzh1PBEnxWPI0j gyYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:x-gm-message-state:delivered-to:sender:from:to:cc :subject:date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=SC8uAIF6Z00RjgDK0+cI2cmYZ34ViAlmgyGeVrDhyP8=; b=M2jnMEO8w/+R6rU9NYwELrFkSEnOSR502h4DxWNPAdGE0U1KzDYydWmnW7GTm6YVTN 5/4lvMxNk1Jdz1TXMGlGxZzNP31k7o07YVTYxHuTcpRpE58hXxWdV2HKVvt7t1aNcyZ3 AB/ND0KkGkhBeQuvdr4p589SMLQKyAA47LKda/nJaM+St2JyXbPY3JaXL+Y+hJ5p6LVF Cwz/M074v86KPWQcsHLvSknoKDV9yQGNNbfVyypuDNIxfOtjwraYPapQC5BESwPkqnmK H2Zg7p7lrId85dG1G27ddiu3HlBEPQT3I8TaEUgqk7GTY5R/EC866aNqzhakFqulMdf6 E9PA== X-Received: by 10.224.173.4 with SMTP id n4mr13070474qaz.3.1377180895334; Thu, 22 Aug 2013 07:14:55 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.71.168 with SMTP id w8ls1064360qeu.64.gmail; Thu, 22 Aug 2013 07:14:55 -0700 (PDT) X-Received: by 10.52.0.108 with SMTP id 12mr64705vdd.45.1377180895255; Thu, 22 Aug 2013 07:14:55 -0700 (PDT) Received: from mail-vb0-x22a.google.com (mail-vb0-x22a.google.com [2607:f8b0:400c:c02::22a]) by mx.google.com with ESMTPS id wk9si4017366vdb.29.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 22 Aug 2013 07:14:55 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400c:c02::22a is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=2607:f8b0:400c:c02::22a; Received: by mail-vb0-f42.google.com with SMTP id e12so1277383vbg.15 for ; Thu, 22 Aug 2013 07:14:55 -0700 (PDT) X-Gm-Message-State: ALoCoQlCQRqfqUUY9RD7OAKQ/82Utgm4gFJDnNcEyjGwF5WXpHFMAvHuW630eLcRgIKw/SsqMNli X-Received: by 10.58.127.202 with SMTP id ni10mr1038575veb.27.1377180895154; Thu, 22 Aug 2013 07:14:55 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp33224vcz; Thu, 22 Aug 2013 07:14:54 -0700 (PDT) X-Received: by 10.204.189.144 with SMTP id de16mr2591566bkb.26.1377180893965; Thu, 22 Aug 2013 07:14:53 -0700 (PDT) Received: from mail-bk0-x231.google.com (mail-bk0-x231.google.com [2a00:1450:4008:c01::231]) by mx.google.com with ESMTPS id jz2si2299724bkb.313.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 22 Aug 2013 07:14:53 -0700 (PDT) Received-SPF: pass (google.com: domain of rric.net@gmail.com designates 2a00:1450:4008:c01::231 as permitted sender) client-ip=2a00:1450:4008:c01::231; Received: by mail-bk0-f49.google.com with SMTP id r7so701246bkg.36 for ; Thu, 22 Aug 2013 07:14:53 -0700 (PDT) X-Received: by 10.204.69.12 with SMTP id x12mr10619023bki.14.1377180892891; Thu, 22 Aug 2013 07:14:52 -0700 (PDT) Received: from rric.localhost (g224195237.adsl.alicedsl.de. [92.224.195.237]) by mx.google.com with ESMTPSA id jh13sm3079991bkb.13.1969.12.31.16.00.00 (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 22 Aug 2013 07:14:52 -0700 (PDT) Sender: Robert Richter From: Robert Richter To: Peter Zijlstra Cc: Ingo Molnar , Arnaldo Carvalho de Melo , Borislav Petkov , Jiri Olsa , linux-kernel@vger.kernel.org, Robert Richter , Robert Richter Subject: [PATCH v3 11/12] perf, persistent: Dynamically resize list of sysfs entries Date: Thu, 22 Aug 2013 16:13:26 +0200 Message-Id: <1377180807-12758-12-git-send-email-rric@kernel.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1377180807-12758-1-git-send-email-rric@kernel.org> References: <1377180807-12758-1-git-send-email-rric@kernel.org> X-Original-Sender: rric.net@gmail.com X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 2607:f8b0:400c:c02::22a is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org; dkim=pass header.i=@gmail.com Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Robert Richter There was a limitation of the total number of persistent events to be registered in sysfs due to the lack of dynamically list allocation. This patch implements memory reallocation in case an event is added or removed from the list. While at this also implement pevent_sysfs_unregister() which we need later for proper event removal. Signed-off-by: Robert Richter Signed-off-by: Robert Richter --- kernel/events/persistent.c | 115 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 99 insertions(+), 16 deletions(-) diff --git a/kernel/events/persistent.c b/kernel/events/persistent.c index 70446ae..a0ef6d4 100644 --- a/kernel/events/persistent.c +++ b/kernel/events/persistent.c @@ -154,6 +154,7 @@ static void persistent_event_close(int cpu, struct pevent *pevent) } static int pevent_sysfs_register(struct pevent *event); +static void pevent_sysfs_unregister(struct pevent *event); static int __maybe_unused persistent_open(char *name, struct perf_event_attr *attr, int nr_pages) @@ -204,6 +205,7 @@ persistent_open(char *name, struct perf_event_attr *attr, int nr_pages) __func__, ret); out: if (atomic_dec_and_test(&pevent->refcount)) { + pevent_sysfs_unregister(pevent); if (pevent->id) put_event_id(pevent->id); kfree(pevent->name); @@ -273,13 +275,12 @@ static struct attribute_group persistent_format_group = { .attrs = persistent_format_attrs, }; -#define MAX_EVENTS 16 - -static struct attribute *pevents_attr[MAX_EVENTS + 1] = { }; +static struct mutex sysfs_lock; +static int sysfs_nr_entries; static struct attribute_group pevents_group = { .name = "events", - .attrs = pevents_attr, + .attrs = NULL, /* dynamically allocated */ }; static const struct attribute_group *persistent_attr_groups[] = { @@ -288,6 +289,7 @@ static const struct attribute_group *persistent_attr_groups[] = { NULL, }; #define EVENTS_GROUP_PTR (&persistent_attr_groups[1]) +#define EVENTS_ATTRS_PTR (&pevents_group.attrs) static ssize_t pevent_sysfs_show(struct device *dev, struct device_attribute *__attr, char *page) @@ -304,7 +306,9 @@ static int pevent_sysfs_register(struct pevent *pevent) struct attribute *attr = &sysfs->attr.attr; struct device *dev = persistent_pmu.dev; const struct attribute_group **group = EVENTS_GROUP_PTR; - int idx; + struct attribute ***attrs_ptr = EVENTS_ATTRS_PTR; + struct attribute **attrs; + int ret = 0; sysfs->id = pevent->id; sysfs->attr = (struct device_attribute) @@ -312,21 +316,99 @@ static int pevent_sysfs_register(struct pevent *pevent) attr->name = pevent->name; sysfs_attr_init(attr); - /* add sysfs attr to events: */ - for (idx = 0; idx < MAX_EVENTS; idx++) { - if (!cmpxchg(pevents_attr + idx, NULL, attr)) - break; + mutex_lock(&sysfs_lock); + + /* + * Keep old list if no new one is available. Need this for + * device_remove_attrs() if unregistering pmu. + */ + attrs = __krealloc(*attrs_ptr, (sysfs_nr_entries + 2) * sizeof(*attrs), + GFP_KERNEL); + + if (!attrs) { + ret = -ENOMEM; + goto unlock; } - if (idx >= MAX_EVENTS) - return -ENOSPC; - if (!idx) + attrs[sysfs_nr_entries++] = attr; + attrs[sysfs_nr_entries] = NULL; + + if (!*group) *group = &pevents_group; + + if (!dev) + goto out; /* sysfs not yet initialized */ + + if (sysfs_nr_entries == 1) + ret = sysfs_create_group(&dev->kobj, *group); + else + ret = sysfs_add_file_to_group(&dev->kobj, attr, (*group)->name); + + if (ret) { + /* roll back */ + sysfs_nr_entries--; + if (!sysfs_nr_entries) + *group = NULL; + if (*attrs_ptr != attrs) + kfree(attrs); + else + attrs[sysfs_nr_entries] = NULL; + goto unlock; + } +out: + if (*attrs_ptr != attrs) { + kfree(*attrs_ptr); + *attrs_ptr = attrs; + } +unlock: + mutex_unlock(&sysfs_lock); + + return ret; +} + +static void pevent_sysfs_unregister(struct pevent *pevent) +{ + struct attribute *attr = &pevent->sysfs.attr.attr; + struct device *dev = persistent_pmu.dev; + const struct attribute_group **group = EVENTS_GROUP_PTR; + struct attribute ***attrs_ptr = EVENTS_ATTRS_PTR; + struct attribute **attrs, **dest; + + mutex_lock(&sysfs_lock); + + for (dest = *attrs_ptr; *dest; dest++) { + if (*dest == attr) + break; + } + + if (!*dest) + goto unlock; + + sysfs_nr_entries--; + + *dest = (*attrs_ptr)[sysfs_nr_entries]; + (*attrs_ptr)[sysfs_nr_entries] = NULL; + if (!dev) - return 0; /* sysfs not yet initialized */ - if (idx) - return sysfs_add_file_to_group(&dev->kobj, attr, (*group)->name); - return sysfs_create_group(&persistent_pmu.dev->kobj, *group); + goto out; /* sysfs not yet initialized */ + + if (!sysfs_nr_entries) + sysfs_remove_group(&dev->kobj, *group); + else + sysfs_remove_file_from_group(&dev->kobj, attr, (*group)->name); +out: + if (!sysfs_nr_entries) + *group = NULL; + + attrs = __krealloc(*attrs_ptr, (sysfs_nr_entries + 1) * sizeof(*attrs), + GFP_KERNEL); + + if (!attrs && *attrs_ptr != attrs) { + kfree(*attrs_ptr); + *attrs_ptr = attrs; + } +unlock: + mutex_unlock(&sysfs_lock); } static int persistent_pmu_init(struct perf_event *event) @@ -349,6 +431,7 @@ void __init perf_register_persistent(void) idr_init(&event_idr); mutex_init(&event_lock); + mutex_init(&sysfs_lock); perf_pmu_register(&persistent_pmu, "persistent", PERF_TYPE_PERSISTENT); for_each_possible_cpu(cpu) {