From patchwork Mon Apr 7 15:04:33 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean Pihet X-Patchwork-Id: 27901 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pd0-f198.google.com (mail-pd0-f198.google.com [209.85.192.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id B43DB20490 for ; Mon, 7 Apr 2014 15:05:50 +0000 (UTC) Received: by mail-pd0-f198.google.com with SMTP id fp1sf23344048pdb.1 for ; Mon, 07 Apr 2014 08:05:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=JgA9sFsabAMGx9kKjor8DDrfB726v4jsBoTkwW6FV54=; b=E1oQjtQifEXITaXV0V1csR5FTUOrOo4Q7o67soloM5TReZQoUWuzIlryhsan/VoMSa B+ibJVpzYBEeNachS6owPEuHyjcuSV0OS/Toj8AfoSllfgIsvxf7JKeyU0BAC2ELG1Z5 CaBjJ+TltME1iU4HMk3ZIEsQX74ITjPkSqZWu9J4Yw24RMBo59pTRin3ErJQbJB2xMmg iJHG+DtdOGyrVJpRB5DzuAd3vmVaH/6+7pAa2i8ERZhxFYk2XmFWCpVWTM4bRXFsKuAo X+bDf+4yiUDpNnldaYZVK0sAgs5B222g6Bl45XMskgp6T+TXoQkd3n7aW4eEurnsKj1t vbVQ== X-Gm-Message-State: ALoCoQmHaxIaLQp6nzgXorOdBwxCvHSUIThLeqgAM+gEIeJadG+fOyMWbiFS2Ea9KNzRReFlzRv1 X-Received: by 10.66.102.36 with SMTP id fl4mr16422905pab.20.1396883149791; Mon, 07 Apr 2014 08:05:49 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.49.112 with SMTP id p103ls1778799qga.41.gmail; Mon, 07 Apr 2014 08:05:49 -0700 (PDT) X-Received: by 10.52.240.207 with SMTP id wc15mr11752174vdc.14.1396883149692; Mon, 07 Apr 2014 08:05:49 -0700 (PDT) Received: from mail-vc0-f177.google.com (mail-vc0-f177.google.com [209.85.220.177]) by mx.google.com with ESMTPS id tm8si3181655vdc.8.2014.04.07.08.05.49 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 07 Apr 2014 08:05:49 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.177 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.177; Received: by mail-vc0-f177.google.com with SMTP id if17so5207218vcb.22 for ; Mon, 07 Apr 2014 08:05:49 -0700 (PDT) X-Received: by 10.220.2.142 with SMTP id 14mr8517vcj.48.1396883149575; Mon, 07 Apr 2014 08:05:49 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.12.8 with SMTP id v8csp169629vcv; Mon, 7 Apr 2014 08:05:49 -0700 (PDT) X-Received: by 10.68.202.194 with SMTP id kk2mr2647927pbc.156.1396883148513; Mon, 07 Apr 2014 08:05:48 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id nm5si8503490pbc.122.2014.04.07.08.05.47; Mon, 07 Apr 2014 08:05:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755497AbaDGPFb (ORCPT + 27 others); Mon, 7 Apr 2014 11:05:31 -0400 Received: from mail-ee0-f41.google.com ([74.125.83.41]:51933 "EHLO mail-ee0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755384AbaDGPFW (ORCPT ); Mon, 7 Apr 2014 11:05:22 -0400 Received: by mail-ee0-f41.google.com with SMTP id t10so750754eei.14 for ; Mon, 07 Apr 2014 08:05:20 -0700 (PDT) X-Received: by 10.14.218.193 with SMTP id k41mr3426846eep.16.1396883120708; Mon, 07 Apr 2014 08:05:20 -0700 (PDT) Received: from localhost.localdomain (201-179-62-37.mobileinternet.proximus.be. [37.62.179.201]) by mx.google.com with ESMTPSA id o4sm42287649eef.20.2014.04.07.08.05.18 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 07 Apr 2014 08:05:19 -0700 (PDT) From: Jean Pihet To: Borislav Petkov , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Jiri Olsa , linux-kernel@vger.kernel.org, Robert Richter Cc: Robert Richter , Jean Pihet Subject: [PATCH 11/16] perf, persistent: Dynamically resize list of sysfs entries Date: Mon, 7 Apr 2014 17:04:33 +0200 Message-Id: <1396883078-25320-12-git-send-email-jean.pihet@linaro.org> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1396883078-25320-1-git-send-email-jean.pihet@linaro.org> References: <1396883078-25320-1-git-send-email-jean.pihet@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: jean.pihet@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.177 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 Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org 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 Signed-off-by: Jean Pihet --- 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 fcbb4f8..49bf889 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 @@ fail: __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) {