From patchwork Wed Aug 13 16:01:29 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lina Iyer X-Patchwork-Id: 35372 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-oa0-f70.google.com (mail-oa0-f70.google.com [209.85.219.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 23EF3203C5 for ; Wed, 13 Aug 2014 16:01:48 +0000 (UTC) Received: by mail-oa0-f70.google.com with SMTP id eb12sf54204782oac.5 for ; Wed, 13 Aug 2014 09:01:47 -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=bRDN9hmuANVaZXZaAHzSpSGYs+px+BzgoTgyLRWNspo=; b=icqdIveHvQ2/HgxcolkhJYGEJB9jLf09D982py+BpEfRxD6UtM3puqoKnZXbEmSbB7 heBjwl7hxyNW4hskPxR5j2N0YIs9xyx8k8q00MINwzAl6yJtYW5PCdcuRJ1A+hbMJNjd Eyyr9gqWcJ2QNiSDpZk43iNiIR91De8YJtEODY8TELoWybY07j1jBNuc4NQd+KYwpXWK SOsULjrn0rZ3JiLKFjy9yhK6+jRf9yEqTBL8KPHGw5sywJ08G3Q1a50eDGSAm1TWGDA3 Wa63Yg4dXEg6UJH3s7R5KygZY9TzENv4entofBa6SpypteLOId2iSEgsa3p4gfhT4YM9 QTWQ== X-Gm-Message-State: ALoCoQnjszv3hRIYKvjDvXrna6VVlaukJ5v4agWIoYQ4GexCfDJRr4X3HGh+JwBTITylhwUQJ7/l X-Received: by 10.42.188.84 with SMTP id cz20mr3233028icb.1.1407945707726; Wed, 13 Aug 2014 09:01:47 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.101.6 with SMTP id t6ls645164qge.32.gmail; Wed, 13 Aug 2014 09:01:47 -0700 (PDT) X-Received: by 10.52.73.202 with SMTP id n10mr1396738vdv.86.1407945707585; Wed, 13 Aug 2014 09:01:47 -0700 (PDT) Received: from mail-vc0-f173.google.com (mail-vc0-f173.google.com [209.85.220.173]) by mx.google.com with ESMTPS id 5si1357766vde.53.2014.08.13.09.01.47 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 13 Aug 2014 09:01:47 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.173 as permitted sender) client-ip=209.85.220.173; Received: by mail-vc0-f173.google.com with SMTP id hy10so15258970vcb.32 for ; Wed, 13 Aug 2014 09:01:47 -0700 (PDT) X-Received: by 10.52.94.108 with SMTP id db12mr146101vdb.8.1407945707513; Wed, 13 Aug 2014 09:01:47 -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.221.37.5 with SMTP id tc5csp342026vcb; Wed, 13 Aug 2014 09:01:46 -0700 (PDT) X-Received: by 10.70.20.99 with SMTP id m3mr4974052pde.14.1407945706361; Wed, 13 Aug 2014 09:01:46 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id rt17si1808213pac.146.2014.08.13.09.01.45 for ; Wed, 13 Aug 2014 09:01:46 -0700 (PDT) Received-SPF: none (google.com: linux-pm-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752831AbaHMQBp (ORCPT + 14 others); Wed, 13 Aug 2014 12:01:45 -0400 Received: from mail-pa0-f50.google.com ([209.85.220.50]:35288 "EHLO mail-pa0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751557AbaHMQBo (ORCPT ); Wed, 13 Aug 2014 12:01:44 -0400 Received: by mail-pa0-f50.google.com with SMTP id et14so15124866pad.37 for ; Wed, 13 Aug 2014 09:01:44 -0700 (PDT) X-Received: by 10.66.174.107 with SMTP id br11mr4878119pac.105.1407945703999; Wed, 13 Aug 2014 09:01:43 -0700 (PDT) Received: from ubuntu.localdomain (proxy6-global253.qualcomm.com. [199.106.103.253]) by mx.google.com with ESMTPSA id wj10sm2518679pbc.67.2014.08.13.09.01.42 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 13 Aug 2014 09:01:43 -0700 (PDT) From: Lina Iyer To: daniel.lezcano@linaro.org, khilman@linaro.org, ulf.hansson@linaro.org, linux-pm@vger.kernel.org, tglx@linutronix.de, rjw@rjwysocki.net Cc: Lina Iyer , Praveen Chidambaram Subject: [PATCH v2 4/4] QoS: Enable PM QoS requests to apply only on smp_affinity of an IRQ Date: Wed, 13 Aug 2014 10:01:29 -0600 Message-Id: <1407945689-18494-5-git-send-email-lina.iyer@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1407945689-18494-1-git-send-email-lina.iyer@linaro.org> References: <1407945689-18494-1-git-send-email-lina.iyer@linaro.org> Sender: linux-pm-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: lina.iyer@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.173 as permitted sender) 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: , QoS requests that need to track an IRQ can be set to apply only on the cpus to which the IRQ's smp_affinity attribute is set to. The PM QoS framework will automatically track IRQ migration between the cores. The QoS is updated to be applied only to the core(s) that the IRQ has been migrated to. The userspace sysfs interface does not support IRQ affinity. Signed-off-by: Praveen Chidambaram Signed-off-by: Lina Iyer --- Documentation/power/pm_qos_interface.txt | 4 +- include/linux/pm_qos.h | 5 +++ kernel/power/qos.c | 77 +++++++++++++++++++++++++++++++- 3 files changed, 84 insertions(+), 2 deletions(-) diff --git a/Documentation/power/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt index c129517..32b864d 100644 --- a/Documentation/power/pm_qos_interface.txt +++ b/Documentation/power/pm_qos_interface.txt @@ -47,8 +47,10 @@ applies to all cores. However, the driver can also specify a request type to be either of PM_QOS_REQ_ALL_CORES, PM_QOS_REQ_AFFINE_CORES, + PM_QOS_REQ_AFFINE_IRQ, -Specify the cpumask when type is set to PM_QOS_REQ_AFFINE_CORES. +Specify the cpumask when type is set to PM_QOS_REQ_AFFINE_CORES and specify +the IRQ number with PM_QOS_REQ_AFFINE_IRQ. void pm_qos_update_request(handle, new_target_value): Will update the list element pointed to by the handle with the new target value diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index a3aa5b5..68b16b8 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -11,6 +11,7 @@ #include #include #include +#include enum { PM_QOS_RESERVED = 0, @@ -45,12 +46,16 @@ enum pm_qos_flags_status { enum pm_qos_req_type { PM_QOS_REQ_ALL_CORES = 0, PM_QOS_REQ_AFFINE_CORES, + PM_QOS_REQ_AFFINE_IRQ, }; struct pm_qos_request { enum pm_qos_req_type type; struct cpumask cpus_affine; + uint32_t irq; /* Internal structure members */ + struct irq_affinity_notify irq_notify; + struct completion irq_released; struct plist_node node; int pm_qos_class; struct delayed_work work; /* for pm_qos_update_request_timeout */ diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 27f84a2..c10e8bc 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -41,6 +41,9 @@ #include #include #include +#include +#include +#include #include #include @@ -412,6 +415,37 @@ static void pm_qos_work_fn(struct work_struct *work) __pm_qos_update_request(req, PM_QOS_DEFAULT_VALUE); } +static void pm_qos_irq_release(struct kref *ref) +{ + unsigned long flags; + struct irq_affinity_notify *notify = container_of(ref, + struct irq_affinity_notify, kref); + struct pm_qos_request *req = container_of(notify, + struct pm_qos_request, irq_notify); + + spin_lock_irqsave(&pm_qos_lock, flags); + cpumask_clear(&req->cpus_affine); + spin_unlock_irqrestore(&pm_qos_lock, flags); + + complete(&req->irq_released); +} + +static void pm_qos_irq_notify(struct irq_affinity_notify *notify, + const cpumask_t *mask) +{ + unsigned long flags; + struct pm_qos_request *req = container_of(notify, + struct pm_qos_request, irq_notify); + struct pm_qos_constraints *c = + pm_qos_array[req->pm_qos_class]->constraints; + + spin_lock_irqsave(&pm_qos_lock, flags); + cpumask_copy(&req->cpus_affine, mask); + spin_unlock_irqrestore(&pm_qos_lock, flags); + + pm_qos_update_target(c, req, PM_QOS_UPDATE_REQ, req->node.prio); +} + /** * pm_qos_add_request - inserts new qos request into the list * @req: pointer to a preallocated handle @@ -445,6 +479,34 @@ void pm_qos_add_request(struct pm_qos_request *req, } break; + case PM_QOS_REQ_AFFINE_IRQ: + if (irq_can_set_affinity(req->irq)) { + int ret = 0; + struct irq_desc *desc = irq_to_desc(req->irq); + struct cpumask *mask = desc->irq_data.affinity; + + /* Get the current affinity */ + cpumask_copy(&req->cpus_affine, mask); + req->irq_notify.irq = req->irq; + req->irq_notify.notify = pm_qos_irq_notify; + req->irq_notify.release = pm_qos_irq_release; + + ret = irq_set_affinity_notifier(req->irq, + &req->irq_notify); + if (ret) { + WARN(1, KERN_ERR "IRQ affinity notify set failed\n"); + req->type = PM_QOS_REQ_ALL_CORES; + cpumask_setall(&req->cpus_affine); + } + } else { + req->type = PM_QOS_REQ_ALL_CORES; + cpumask_setall(&req->cpus_affine); + WARN(1, KERN_ERR "IRQ-%d not set for request with affinity flag\n", + req->irq); + } + init_completion(&req->irq_released); + break; + default: WARN(1, KERN_ERR "Unknown request type %d\n", req->type); /* fall through */ @@ -526,11 +588,14 @@ void pm_qos_update_request_timeout(struct pm_qos_request *req, s32 new_value, */ void pm_qos_remove_request(struct pm_qos_request *req) { - if (!req) /*guard against callers passing in null */ return; /* silent return to keep pcm code cleaner */ + /* Remove ourselves from the irq notification */ + if (req->type == PM_QOS_REQ_AFFINE_IRQ) + irq_release_affinity_notifier(&req->irq_notify); + if (!pm_qos_request_active(req)) { WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown object\n"); return; @@ -543,6 +608,16 @@ void pm_qos_remove_request(struct pm_qos_request *req) req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); + /** + * The 'release' callback of the notifier would not be called unless + * there are no active users of the irq_notify object, i.e, kref count + * is non-zero. This could happen if there is an active 'notify' + * callback happening while the pm_qos_remove request is called. Wait + * until the release callback clears the cpus_affine mask. + */ + if (req->type == PM_QOS_REQ_AFFINE_IRQ) + wait_for_completion(&req->irq_released); + memset(req, 0, sizeof(*req)); } EXPORT_SYMBOL_GPL(pm_qos_remove_request);