From patchwork Wed Aug 27 20:14:39 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lina Iyer X-Patchwork-Id: 36139 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ig0-f200.google.com (mail-ig0-f200.google.com [209.85.213.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 1E3F62054F for ; Wed, 27 Aug 2014 20:16:10 +0000 (UTC) Received: by mail-ig0-f200.google.com with SMTP id uq10sf3543374igb.3 for ; Wed, 27 Aug 2014 13:16:09 -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=L8mZPe9u9FIfU22K2GODnebgOiYqTYwk4QjpeIjNFxs=; b=Uu5Bp9y8PeoIc1hkrg4CHz1VBlxFffOAn99JvEs0fZd2KClCVrPcl/SDWR9Z8RkBXs m5Sj97etMyDqrHjE/08JEgALZzFTCt5Hi5401NLB4F9cqMXGriCcCVvB8NssMdcpJD9L G0aHaGMzbAA6OEwzKXvzKU7sNRyiP3V2qfTpbx+/kQ3L3+8FH2AHjonRynZF3CSIGHg3 fpRQYxhnEMDiGjgjTS5s/DiEITXhb20LdqFPlRgqY2bc3bAkkbGsYEURiq8/DgttdECE zdN2AfFKWxXKfzRm7kyZme8s8VBaMK1mqdqTRkQtcs42be5/gtYrlucK4+DF0cqWwq22 lu/Q== X-Gm-Message-State: ALoCoQkwk+XRh4vkSTyeYaBuqEXfU4Fw14BbU9tk17qvQz80bKvA0FQbyKCJ1TuS/eWdT3FmIPW/ X-Received: by 10.182.91.43 with SMTP id cb11mr24402239obb.13.1409170569658; Wed, 27 Aug 2014 13:16:09 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.86.9 with SMTP id o9ls258316qgd.47.gmail; Wed, 27 Aug 2014 13:16:09 -0700 (PDT) X-Received: by 10.220.166.68 with SMTP id l4mr6496666vcy.20.1409170569551; Wed, 27 Aug 2014 13:16:09 -0700 (PDT) Received: from mail-vc0-f171.google.com (mail-vc0-f171.google.com [209.85.220.171]) by mx.google.com with ESMTPS id vx5si1888855vcb.0.2014.08.27.13.16.09 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 27 Aug 2014 13:16:09 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.171 as permitted sender) client-ip=209.85.220.171; Received: by mail-vc0-f171.google.com with SMTP id hy10so205438vcb.16 for ; Wed, 27 Aug 2014 13:16:09 -0700 (PDT) X-Received: by 10.220.77.65 with SMTP id f1mr3162591vck.48.1409170569409; Wed, 27 Aug 2014 13:16:09 -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.45.67 with SMTP id uj3csp134131vcb; Wed, 27 Aug 2014 13:16:08 -0700 (PDT) X-Received: by 10.66.141.229 with SMTP id rr5mr34363908pab.24.1409170568390; Wed, 27 Aug 2014 13:16:08 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id gp10si2327099pbd.167.2014.08.27.13.16.07 for ; Wed, 27 Aug 2014 13:16:08 -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 S935792AbaH0UPs (ORCPT + 15 others); Wed, 27 Aug 2014 16:15:48 -0400 Received: from mail-pa0-f54.google.com ([209.85.220.54]:46525 "EHLO mail-pa0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935760AbaH0UPr (ORCPT ); Wed, 27 Aug 2014 16:15:47 -0400 Received: by mail-pa0-f54.google.com with SMTP id fa1so1171517pad.41 for ; Wed, 27 Aug 2014 13:15:46 -0700 (PDT) X-Received: by 10.70.10.100 with SMTP id h4mr25409722pdb.162.1409170546792; Wed, 27 Aug 2014 13:15:46 -0700 (PDT) Received: from ubuntu.localdomain (70-59-28-129.hlrn.qwest.net. [70.59.28.129]) by mx.google.com with ESMTPSA id ol8sm1868447pdb.82.2014.08.27.13.15.44 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 27 Aug 2014 13:15:46 -0700 (PDT) From: Lina Iyer To: khilman@linaro.org, ulf.hansson@linaro.org, linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, tglx@linutronix.de, rjw@rjwysocki.net Cc: daniel.lezcano@linaro.org, Lina Iyer , Praveen Chidambaram Subject: [PATCH v3 4/4] QoS: Enable PM QoS requests to apply only on smp_affinity of an IRQ Date: Wed, 27 Aug 2014 14:14:39 -0600 Message-Id: <1409170479-29955-5-git-send-email-lina.iyer@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1409170479-29955-1-git-send-email-lina.iyer@linaro.org> References: <1409170479-29955-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.171 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: , Based on original work by pchidamb@codeaurora.org. 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 [lina.iyer: Split the change from a previous change, add commit text] 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);