From patchwork Tue Feb 9 06:24:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrian Hunter X-Patchwork-Id: 12077217 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6547FC433E0 for ; Tue, 9 Feb 2021 06:26:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3166864E45 for ; Tue, 9 Feb 2021 06:26:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230241AbhBIGZs (ORCPT ); Tue, 9 Feb 2021 01:25:48 -0500 Received: from mga07.intel.com ([134.134.136.100]:37171 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230183AbhBIGZV (ORCPT ); Tue, 9 Feb 2021 01:25:21 -0500 IronPort-SDR: xncUHIOJlIidHgPfvnHcqgku9w8UPZlTBq2ka9SRS0OndOo1sktckJIwj5v3Y/9JHW7IDFrZVh /xMx6w1IGiWQ== X-IronPort-AV: E=McAfee;i="6000,8403,9889"; a="245904363" X-IronPort-AV: E=Sophos;i="5.81,164,1610438400"; d="scan'208";a="245904363" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2021 22:24:41 -0800 IronPort-SDR: akQes4JlNVqeFGDLbgIYq/YT+drWBmZUKTyEPZUROLF3xxwY076XB9GG8ULVstCmG0A1fWa17B 44LLQz0Da1DQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,164,1610438400"; d="scan'208";a="398681946" Received: from ahunter-desktop.fi.intel.com ([10.237.72.149]) by orsmga007.jf.intel.com with ESMTP; 08 Feb 2021 22:24:38 -0800 From: Adrian Hunter To: "Martin K . Petersen" , "James E . J . Bottomley" Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Alim Akhtar , Avri Altman , Bean Huo , Can Guo , Stanley Chu Subject: [PATCH V2 1/4] scsi: ufs: Add exception event tracepoint Date: Tue, 9 Feb 2021 08:24:34 +0200 Message-Id: <20210209062437.6954-2-adrian.hunter@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210209062437.6954-1-adrian.hunter@intel.com> References: <20210209062437.6954-1-adrian.hunter@intel.com> Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Currently, exception event status can be read from wExceptionEventStatus attribute (sysfs file attributes/exception_event_status under the UFS host controller device directory). Polling that attribute to track UFS exception events is impractical, so add a tracepoint to track exception events for testing and debugging purposes. Note, by the time the exception event status is read, the exception event may have cleared, so the value can be zero - see example below. Note also, only enabled exception events can be reported. A subsequent patch adds the ability for users to enable selected exception events via debugfs. Example with driver instrumented to enable all exception events: # echo 1 > /sys/kernel/debug/tracing/events/ufs/ufshcd_exception_event/enable ... do some I/O ... # cat /sys/kernel/debug/tracing/trace # tracer: nop # # entries-in-buffer/entries-written: 3/3 #P:5 # # _-----=> irqs-off # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / delay # TASK-PID CPU# |||| TIMESTAMP FUNCTION # | | | |||| | | kworker/2:2-173 [002] .... 731.486419: ufshcd_exception_event: 0000:00:12.5: status 0x0 kworker/2:2-173 [002] .... 732.608918: ufshcd_exception_event: 0000:00:12.5: status 0x4 kworker/2:2-173 [002] .... 732.609312: ufshcd_exception_event: 0000:00:12.5: status 0x4 Signed-off-by: Adrian Hunter Reviewed-by: Avri Altman Reviewed-by: Bean Huo --- drivers/scsi/ufs/ufshcd.c | 2 ++ include/trace/events/ufs.h | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 721f55db181f..d6fdce655388 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5616,6 +5616,8 @@ static void ufshcd_exception_event_handler(struct work_struct *work) goto out; } + trace_ufshcd_exception_event(dev_name(hba->dev), status); + status &= hba->ee_ctrl_mask; if (status & MASK_EE_URGENT_BKOPS) diff --git a/include/trace/events/ufs.h b/include/trace/events/ufs.h index e151477d645c..1cb6f1afba0e 100644 --- a/include/trace/events/ufs.h +++ b/include/trace/events/ufs.h @@ -349,6 +349,27 @@ TRACE_EVENT(ufshcd_upiu, ) ); +TRACE_EVENT(ufshcd_exception_event, + + TP_PROTO(const char *dev_name, u16 status), + + TP_ARGS(dev_name, status), + + TP_STRUCT__entry( + __string(dev_name, dev_name) + __field(u16, status) + ), + + TP_fast_assign( + __assign_str(dev_name, dev_name); + __entry->status = status; + ), + + TP_printk("%s: status 0x%x", + __get_str(dev_name), __entry->status + ) +); + #endif /* if !defined(_TRACE_UFS_H) || defined(TRACE_HEADER_MULTI_READ) */ /* This part must be outside protection */ From patchwork Tue Feb 9 06:24:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrian Hunter X-Patchwork-Id: 12077221 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9DD81C433E9 for ; Tue, 9 Feb 2021 06:26:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6D7E864EB9 for ; Tue, 9 Feb 2021 06:26:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230263AbhBIG0G (ORCPT ); Tue, 9 Feb 2021 01:26:06 -0500 Received: from mga07.intel.com ([134.134.136.100]:37175 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230238AbhBIGZY (ORCPT ); Tue, 9 Feb 2021 01:25:24 -0500 IronPort-SDR: MBI6W8AgSej/AZ9ffwTCKcLo8BHMGPOrH90qRd5mHp6pJZc8aKMOAHnPgSC7G3YPeh1ZoCyi/Q 5D8rggeRENKQ== X-IronPort-AV: E=McAfee;i="6000,8403,9889"; a="245904366" X-IronPort-AV: E=Sophos;i="5.81,164,1610438400"; d="scan'208";a="245904366" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2021 22:24:44 -0800 IronPort-SDR: O4F4OmzKXgvycv2r781oHsiJhDKsT7SuUUYawavI1rK3amF72xk6JRrjpfUDSSgyDEZUL0JAb3 e0bzgfP6qvZA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,164,1610438400"; d="scan'208";a="398681952" Received: from ahunter-desktop.fi.intel.com ([10.237.72.149]) by orsmga007.jf.intel.com with ESMTP; 08 Feb 2021 22:24:41 -0800 From: Adrian Hunter To: "Martin K . Petersen" , "James E . J . Bottomley" Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Alim Akhtar , Avri Altman , Bean Huo , Can Guo , Stanley Chu Subject: [PATCH V2 2/4] scsi: ufs: Add exception event definitions Date: Tue, 9 Feb 2021 08:24:35 +0200 Message-Id: <20210209062437.6954-3-adrian.hunter@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210209062437.6954-1-adrian.hunter@intel.com> References: <20210209062437.6954-1-adrian.hunter@intel.com> Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org For readability and completeness, add exception event definitions. Signed-off-by: Adrian Hunter Reviewed-by: Bean Huo --- drivers/scsi/ufs/ufs.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index bf1897a72532..cb80b9670bfe 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -348,8 +348,14 @@ enum power_desc_param_offset { /* Exception event mask values */ enum { - MASK_EE_STATUS = 0xFFFF, - MASK_EE_URGENT_BKOPS = (1 << 2), + MASK_EE_STATUS = 0xFFFF, + MASK_EE_DYNCAP_EVENT = BIT(0), + MASK_EE_SYSPOOL_EVENT = BIT(1), + MASK_EE_URGENT_BKOPS = BIT(2), + MASK_EE_TOO_HIGH_TEMP = BIT(3), + MASK_EE_TOO_LOW_TEMP = BIT(4), + MASK_EE_WRITEBOOSTER_EVENT = BIT(5), + MASK_EE_PERFORMANCE_THROTTLING = BIT(6), }; /* Background operation status */ From patchwork Tue Feb 9 06:24:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrian Hunter X-Patchwork-Id: 12077223 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 190BCC433DB for ; Tue, 9 Feb 2021 06:26:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D40DC64E54 for ; Tue, 9 Feb 2021 06:26:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230269AbhBIG0O (ORCPT ); Tue, 9 Feb 2021 01:26:14 -0500 Received: from mga07.intel.com ([134.134.136.100]:37168 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230250AbhBIG0C (ORCPT ); Tue, 9 Feb 2021 01:26:02 -0500 IronPort-SDR: CH2sR/7IvAgJYaVn1tWNRu1ibPxg86y5M2vuLpNh8HeN/6DVbnHMNSLa3cYfKiFcp1RXetsTRT DzYv/F6iOZmw== X-IronPort-AV: E=McAfee;i="6000,8403,9889"; a="245904367" X-IronPort-AV: E=Sophos;i="5.81,164,1610438400"; d="scan'208";a="245904367" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2021 22:24:46 -0800 IronPort-SDR: ObTc+4p0aZ0eWTl6WhlAM1I8fRJmmPTA1pcWy82woEAl1MGskcRA/SQz5fQRUAd1jBlmNaEhM3 IBVH8D6/J4rQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,164,1610438400"; d="scan'208";a="398681958" Received: from ahunter-desktop.fi.intel.com ([10.237.72.149]) by orsmga007.jf.intel.com with ESMTP; 08 Feb 2021 22:24:44 -0800 From: Adrian Hunter To: "Martin K . Petersen" , "James E . J . Bottomley" Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Alim Akhtar , Avri Altman , Bean Huo , Can Guo , Stanley Chu Subject: [PATCH V2 3/4] scsi: ufs-debugfs: Add user-defined exception_event_mask Date: Tue, 9 Feb 2021 08:24:36 +0200 Message-Id: <20210209062437.6954-4-adrian.hunter@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210209062437.6954-1-adrian.hunter@intel.com> References: <20210209062437.6954-1-adrian.hunter@intel.com> Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Allow users to enable specific exception events via debugfs. The bits enabled by the driver ee_drv_ctrl are separated from the bits enabled by the user ee_usr_ctrl. The control mask ee_mask_ctrl is the logical-or of those two. A mutex is needed to ensure that the masks match what was written to the device. Signed-off-by: Adrian Hunter Acked-by: Bean Huo --- drivers/scsi/ufs/ufs-debugfs.c | 46 ++++++++++++++++++ drivers/scsi/ufs/ufshcd.c | 86 +++++++++++++++++++++------------- drivers/scsi/ufs/ufshcd.h | 22 ++++++++- 3 files changed, 120 insertions(+), 34 deletions(-) diff --git a/drivers/scsi/ufs/ufs-debugfs.c b/drivers/scsi/ufs/ufs-debugfs.c index dee98dc72d29..59729073b569 100644 --- a/drivers/scsi/ufs/ufs-debugfs.c +++ b/drivers/scsi/ufs/ufs-debugfs.c @@ -44,10 +44,56 @@ static int ufs_debugfs_stats_show(struct seq_file *s, void *data) } DEFINE_SHOW_ATTRIBUTE(ufs_debugfs_stats); +static int ee_usr_mask_get(void *data, u64 *val) +{ + struct ufs_hba *hba = data; + + *val = hba->ee_usr_mask; + return 0; +} + +static int ufs_debugfs_get_user_access(struct ufs_hba *hba) +__acquires(&hba->host_sem) +{ + down(&hba->host_sem); + if (!ufshcd_is_user_access_allowed(hba)) { + up(&hba->host_sem); + return -EBUSY; + } + pm_runtime_get_sync(hba->dev); + return 0; +} + +static void ufs_debugfs_put_user_access(struct ufs_hba *hba) +__releases(&hba->host_sem) +{ + pm_runtime_put_sync(hba->dev); + up(&hba->host_sem); +} + +static int ee_usr_mask_set(void *data, u64 val) +{ + struct ufs_hba *hba = data; + int err; + + if (val & ~(u64)MASK_EE_STATUS) + return -EINVAL; + err = ufs_debugfs_get_user_access(hba); + if (err) + return err; + err = ufshcd_update_ee_usr_mask(hba, val, MASK_EE_STATUS); + ufs_debugfs_put_user_access(hba); + return err; +} + +DEFINE_DEBUGFS_ATTRIBUTE(ee_usr_mask_fops, ee_usr_mask_get, ee_usr_mask_set, "%#llx\n"); + void ufs_debugfs_hba_init(struct ufs_hba *hba) { hba->debugfs_root = debugfs_create_dir(dev_name(hba->dev), ufs_debugfs_root); debugfs_create_file("stats", 0400, hba->debugfs_root, hba, &ufs_debugfs_stats_fops); + debugfs_create_file("exception_event_mask", 0600, hba->debugfs_root, + hba, &ee_usr_mask_fops); } void ufs_debugfs_hba_exit(struct ufs_hba *hba) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index d6fdce655388..065a662e7886 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5160,6 +5160,46 @@ static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) } } +static int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask) +{ + return ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, + QUERY_ATTR_IDN_EE_CONTROL, 0, 0, + &ee_ctrl_mask); +} + +static int ufshcd_write_ee_control(struct ufs_hba *hba) +{ + int err; + + mutex_lock(&hba->ee_ctrl_mutex); + err = __ufshcd_write_ee_control(hba, hba->ee_ctrl_mask); + mutex_unlock(&hba->ee_ctrl_mutex); + if (err) + dev_err(hba->dev, "%s: failed to write ee control %d\n", + __func__, err); + return err; +} + +int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, u16 *other_mask, + u16 set, u16 clr) +{ + u16 new_mask, ee_ctrl_mask; + int err = 0; + + mutex_lock(&hba->ee_ctrl_mutex); + new_mask = (*mask & ~clr) | set; + ee_ctrl_mask = new_mask | *other_mask; + if (ee_ctrl_mask != hba->ee_ctrl_mask) + err = __ufshcd_write_ee_control(hba, ee_ctrl_mask); + /* Still need to update 'mask' even if 'ee_ctrl_mask' was unchanged */ + if (!err) { + hba->ee_ctrl_mask = ee_ctrl_mask; + *mask = new_mask; + } + mutex_unlock(&hba->ee_ctrl_mutex); + return err; +} + /** * ufshcd_disable_ee - disable exception event * @hba: per-adapter instance @@ -5170,22 +5210,9 @@ static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) * * Returns zero on success, non-zero error value on failure. */ -static int ufshcd_disable_ee(struct ufs_hba *hba, u16 mask) +static inline int ufshcd_disable_ee(struct ufs_hba *hba, u16 mask) { - int err = 0; - u32 val; - - if (!(hba->ee_ctrl_mask & mask)) - goto out; - - val = hba->ee_ctrl_mask & ~mask; - val &= MASK_EE_STATUS; - err = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, - QUERY_ATTR_IDN_EE_CONTROL, 0, 0, &val); - if (!err) - hba->ee_ctrl_mask &= ~mask; -out: - return err; + return ufshcd_update_ee_drv_mask(hba, 0, mask); } /** @@ -5198,22 +5225,9 @@ static int ufshcd_disable_ee(struct ufs_hba *hba, u16 mask) * * Returns zero on success, non-zero error value on failure. */ -static int ufshcd_enable_ee(struct ufs_hba *hba, u16 mask) +static inline int ufshcd_enable_ee(struct ufs_hba *hba, u16 mask) { - int err = 0; - u32 val; - - if (hba->ee_ctrl_mask & mask) - goto out; - - val = hba->ee_ctrl_mask | mask; - val &= MASK_EE_STATUS; - err = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, - QUERY_ATTR_IDN_EE_CONTROL, 0, 0, &val); - if (!err) - hba->ee_ctrl_mask |= mask; -out: - return err; + return ufshcd_update_ee_drv_mask(hba, mask, 0); } /** @@ -5618,9 +5632,7 @@ static void ufshcd_exception_event_handler(struct work_struct *work) trace_ufshcd_exception_event(dev_name(hba->dev), status); - status &= hba->ee_ctrl_mask; - - if (status & MASK_EE_URGENT_BKOPS) + if (status & hba->ee_drv_mask & MASK_EE_URGENT_BKOPS) ufshcd_bkops_exception_event_handler(hba); out: @@ -7921,6 +7933,8 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async) ufshcd_set_active_icc_lvl(hba); ufshcd_wb_config(hba); + if (hba->ee_usr_mask) + ufshcd_write_ee_control(hba); /* Enable Auto-Hibernate if configured */ ufshcd_auto_hibern8_enable(hba); @@ -8918,6 +8932,9 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) */ ufshcd_urgent_bkops(hba); + if (hba->ee_usr_mask) + ufshcd_write_ee_control(hba); + hba->clk_gating.is_suspended = false; if (ufshcd_is_clkscaling_supported(hba)) @@ -9355,6 +9372,9 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) /* Initialize mutex for device management commands */ mutex_init(&hba->dev_cmd.lock); + /* Initialize mutex for exception event control */ + mutex_init(&hba->ee_ctrl_mutex); + init_rwsem(&hba->clk_scaling_lock); ufshcd_init_clk_gating(hba); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index ee61f821f75d..9b7413f35def 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -773,7 +773,10 @@ struct ufs_hba { u32 ufshcd_state; u32 eh_flags; u32 intr_mask; - u16 ee_ctrl_mask; + u16 ee_ctrl_mask; /* Exception event mask */ + u16 ee_drv_mask; /* Exception event mask for driver */ + u16 ee_usr_mask; /* Exception event mask for user (via debugfs) */ + struct mutex ee_ctrl_mutex; bool is_powered; bool shutting_down; struct semaphore host_sem; @@ -1285,4 +1288,21 @@ static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun) int ufshcd_dump_regs(struct ufs_hba *hba, size_t offset, size_t len, const char *prefix); +int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, u16 *other_mask, + u16 set, u16 clr); + +static inline int ufshcd_update_ee_drv_mask(struct ufs_hba *hba, + u16 set, u16 clr) +{ + return ufshcd_update_ee_control(hba, &hba->ee_drv_mask, + &hba->ee_usr_mask, set, clr); +} + +static inline int ufshcd_update_ee_usr_mask(struct ufs_hba *hba, + u16 set, u16 clr) +{ + return ufshcd_update_ee_control(hba, &hba->ee_usr_mask, + &hba->ee_drv_mask, set, clr); +} + #endif /* End of Header */ From patchwork Tue Feb 9 06:24:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrian Hunter X-Patchwork-Id: 12077219 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CF345C433DB for ; Tue, 9 Feb 2021 06:26:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A4CAD64E28 for ; Tue, 9 Feb 2021 06:26:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230270AbhBIG0K (ORCPT ); Tue, 9 Feb 2021 01:26:10 -0500 Received: from mga07.intel.com ([134.134.136.100]:37171 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230234AbhBIG0C (ORCPT ); Tue, 9 Feb 2021 01:26:02 -0500 IronPort-SDR: 2EDz5ejhWfhq895zpPlcmzxP7QNIhc3Kge3QGbbjPsxad9CoF/dehigtXnLKfvE3HFyxq/J8/e 9S+YDJxzkE2w== X-IronPort-AV: E=McAfee;i="6000,8403,9889"; a="245904371" X-IronPort-AV: E=Sophos;i="5.81,164,1610438400"; d="scan'208";a="245904371" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Feb 2021 22:24:49 -0800 IronPort-SDR: OzSmKVPQmDdYTFOCQwxqh9yvNm9mnyjJj/GuMrQ95ot3ycn52Uoqlrphd6Ih0RupLpcsWsKYdi hSGn4+yp1kag== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,164,1610438400"; d="scan'208";a="398681981" Received: from ahunter-desktop.fi.intel.com ([10.237.72.149]) by orsmga007.jf.intel.com with ESMTP; 08 Feb 2021 22:24:47 -0800 From: Adrian Hunter To: "Martin K . Petersen" , "James E . J . Bottomley" Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Alim Akhtar , Avri Altman , Bean Huo , Can Guo , Stanley Chu Subject: [PATCH V2 4/4] scsi: ufs-debugfs: Add user-defined exception event rate limiting Date: Tue, 9 Feb 2021 08:24:37 +0200 Message-Id: <20210209062437.6954-5-adrian.hunter@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210209062437.6954-1-adrian.hunter@intel.com> References: <20210209062437.6954-1-adrian.hunter@intel.com> Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org An enabled user-specified exception event that does not clear quickly will repeatedly cause the handler to run. That could unduly disturb the driver behaviour being tested or debugged. To prevent that add debugfs file exception_event_rate_limit_ms. When a exception event happens, it is disabled, and then after a period of time (default 20ms) the exception event is enabled again. Note that if the driver also has that exception event enabled, it will not be disabled. Signed-off-by: Adrian Hunter Acked-by: Bean Huo --- drivers/scsi/ufs/ufs-debugfs.c | 44 ++++++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufs-debugfs.h | 2 ++ drivers/scsi/ufs/ufshcd.c | 5 ++-- drivers/scsi/ufs/ufshcd.h | 4 ++++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufs-debugfs.c b/drivers/scsi/ufs/ufs-debugfs.c index 59729073b569..ced9ef4d7c78 100644 --- a/drivers/scsi/ufs/ufs-debugfs.c +++ b/drivers/scsi/ufs/ufs-debugfs.c @@ -88,15 +88,59 @@ static int ee_usr_mask_set(void *data, u64 val) DEFINE_DEBUGFS_ATTRIBUTE(ee_usr_mask_fops, ee_usr_mask_get, ee_usr_mask_set, "%#llx\n"); +void ufs_debugfs_exception_event(struct ufs_hba *hba, u16 status) +{ + bool chgd = false; + u16 ee_ctrl_mask; + int err = 0; + + if (!hba->debugfs_ee_rate_limit_ms || !status) + return; + + mutex_lock(&hba->ee_ctrl_mutex); + ee_ctrl_mask = hba->ee_drv_mask | (hba->ee_usr_mask & ~status); + chgd = ee_ctrl_mask != hba->ee_ctrl_mask; + if (chgd) { + err = __ufshcd_write_ee_control(hba, ee_ctrl_mask); + if (err) + dev_err(hba->dev, "%s: failed to write ee control %d\n", + __func__, err); + } + mutex_unlock(&hba->ee_ctrl_mutex); + + if (chgd && !err) { + unsigned long delay = msecs_to_jiffies(hba->debugfs_ee_rate_limit_ms); + + queue_delayed_work(system_freezable_wq, &hba->debugfs_ee_work, delay); + } +} + +static void ufs_debugfs_restart_ee(struct work_struct *work) +{ + struct ufs_hba *hba = container_of(work, struct ufs_hba, debugfs_ee_work.work); + + if (!hba->ee_usr_mask || pm_runtime_suspended(hba->dev) || + ufs_debugfs_get_user_access(hba)) + return; + ufshcd_write_ee_control(hba); + ufs_debugfs_put_user_access(hba); +} + void ufs_debugfs_hba_init(struct ufs_hba *hba) { + /* Set default exception event rate limit period to 20ms */ + hba->debugfs_ee_rate_limit_ms = 20; + INIT_DELAYED_WORK(&hba->debugfs_ee_work, ufs_debugfs_restart_ee); hba->debugfs_root = debugfs_create_dir(dev_name(hba->dev), ufs_debugfs_root); debugfs_create_file("stats", 0400, hba->debugfs_root, hba, &ufs_debugfs_stats_fops); debugfs_create_file("exception_event_mask", 0600, hba->debugfs_root, hba, &ee_usr_mask_fops); + debugfs_create_u32("exception_event_rate_limit_ms", 0600, hba->debugfs_root, + &hba->debugfs_ee_rate_limit_ms); } void ufs_debugfs_hba_exit(struct ufs_hba *hba) { debugfs_remove_recursive(hba->debugfs_root); + cancel_delayed_work_sync(&hba->debugfs_ee_work); } diff --git a/drivers/scsi/ufs/ufs-debugfs.h b/drivers/scsi/ufs/ufs-debugfs.h index f35b39c4b4f5..3ca29d30460a 100644 --- a/drivers/scsi/ufs/ufs-debugfs.h +++ b/drivers/scsi/ufs/ufs-debugfs.h @@ -12,11 +12,13 @@ void __init ufs_debugfs_init(void); void __exit ufs_debugfs_exit(void); void ufs_debugfs_hba_init(struct ufs_hba *hba); void ufs_debugfs_hba_exit(struct ufs_hba *hba); +void ufs_debugfs_exception_event(struct ufs_hba *hba, u16 status); #else static inline void ufs_debugfs_init(void) {} static inline void ufs_debugfs_exit(void) {} static inline void ufs_debugfs_hba_init(struct ufs_hba *hba) {} static inline void ufs_debugfs_hba_exit(struct ufs_hba *hba) {} +static inline void ufs_debugfs_exception_event(struct ufs_hba *hba, u16 status) {} #endif #endif diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 065a662e7886..42d9a96a5721 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5160,14 +5160,14 @@ static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) } } -static int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask) +int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask) { return ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, QUERY_ATTR_IDN_EE_CONTROL, 0, 0, &ee_ctrl_mask); } -static int ufshcd_write_ee_control(struct ufs_hba *hba) +int ufshcd_write_ee_control(struct ufs_hba *hba) { int err; @@ -5635,6 +5635,7 @@ static void ufshcd_exception_event_handler(struct work_struct *work) if (status & hba->ee_drv_mask & MASK_EE_URGENT_BKOPS) ufshcd_bkops_exception_event_handler(hba); + ufs_debugfs_exception_event(hba, status); out: ufshcd_scsi_unblock_requests(hba); /* diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 9b7413f35def..8a52b63ad4e6 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -843,6 +843,8 @@ struct ufs_hba { #endif #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_root; + struct delayed_work debugfs_ee_work; + u32 debugfs_ee_rate_limit_ms; #endif }; @@ -1288,6 +1290,8 @@ static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun) int ufshcd_dump_regs(struct ufs_hba *hba, size_t offset, size_t len, const char *prefix); +int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask); +int ufshcd_write_ee_control(struct ufs_hba *hba); int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, u16 *other_mask, u16 set, u16 clr);