From patchwork Wed Jul 15 13:22:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11665339 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 95CC814E3 for ; Wed, 15 Jul 2020 13:23:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7EF5420720 for ; Wed, 15 Jul 2020 13:23:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="GrzOYeOj" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731703AbgGONXN (ORCPT ); Wed, 15 Jul 2020 09:23:13 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:52454 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731632AbgGONXM (ORCPT ); Wed, 15 Jul 2020 09:23:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1594819391; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eygM6ryWZb9MBz0z7DwJf48GdGrc3KYxU36piBEgFV0=; b=GrzOYeOjvDTg4x3X9wrLa8jqxOgTkEPP5jxUwAuAgfbrGZrziKCPKcDNRlwei0CIiDip/l kiWU07/U2u1RwAI0RR3Fw2aTBBQx7Vj2uGAIsXXNRXNkvC6ZNXxzfpq80ygNDn9k0BtAwS QYc646p/f+FDaYAM00l4rMr35p8ubQ4= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-229-9yvRdy7PMKGV6fjV4YaUiA-1; Wed, 15 Jul 2020 09:23:06 -0400 X-MC-Unique: 9yvRdy7PMKGV6fjV4YaUiA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 6C3CC1083; Wed, 15 Jul 2020 13:23:05 +0000 (UTC) Received: from x1.localdomain.com (ovpn-113-224.ams2.redhat.com [10.36.113.224]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5D66860BF4; Wed, 15 Jul 2020 13:23:04 +0000 (UTC) From: Hans de Goede To: Greg Kroah-Hartman , Guenter Roeck , Heikki Krogerus Cc: Hans de Goede , linux-usb@vger.kernel.org Subject: [PATCH 1/6] usb: typec: tcpm: Move mod_delayed_work(&port->vdm_state_machine) call into tcpm_queue_vdm() Date: Wed, 15 Jul 2020 15:22:56 +0200 Message-Id: <20200715132301.99816-2-hdegoede@redhat.com> In-Reply-To: <20200715132301.99816-1-hdegoede@redhat.com> References: <20200715132301.99816-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org All callers of tcpm_queue_vdm() immediately follow the tcpm_queue_vdm() vdm call with a: mod_delayed_work(port->wq, &port->vdm_state_machine, 0); Call, fold this into tcpm_queue_vdm() itself. Signed-off-by: Hans de Goede Reviewed-by: Guenter Roeck --- drivers/usb/typec/tcpm/tcpm.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index b4a66e6bf68c..fc6455a29c74 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -967,6 +967,8 @@ static void tcpm_queue_vdm(struct tcpm_port *port, const u32 header, /* Set ready, vdm state machine will actually send */ port->vdm_retries = 0; port->vdm_state = VDM_STATE_READY; + + mod_delayed_work(port->wq, &port->vdm_state_machine, 0); } static void svdm_consume_identity(struct tcpm_port *port, const __le32 *payload, @@ -1246,10 +1248,8 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port, if (PD_VDO_SVDM(p0)) rlen = tcpm_pd_svdm(port, payload, cnt, response); - if (rlen > 0) { + if (rlen > 0) tcpm_queue_vdm(port, response[0], &response[1], rlen - 1); - mod_delayed_work(port->wq, &port->vdm_state_machine, 0); - } } static void tcpm_send_vdm(struct tcpm_port *port, u32 vid, int cmd, @@ -1264,8 +1264,6 @@ static void tcpm_send_vdm(struct tcpm_port *port, u32 vid, int cmd, header = VDO(vid, ((vid & USB_SID_PD) == USB_SID_PD) ? 1 : (PD_VDO_CMD(cmd) <= CMD_ATTENTION), cmd); tcpm_queue_vdm(port, header, data, count); - - mod_delayed_work(port->wq, &port->vdm_state_machine, 0); } static unsigned int vdm_ready_timeout(u32 vdm_hdr) @@ -1513,7 +1511,6 @@ static int tcpm_altmode_enter(struct typec_altmode *altmode, u32 *vdo) header |= VDO_OPOS(altmode->mode); tcpm_queue_vdm(port, header, vdo, vdo ? 1 : 0); - mod_delayed_work(port->wq, &port->vdm_state_machine, 0); mutex_unlock(&port->lock); return 0; @@ -1529,7 +1526,6 @@ static int tcpm_altmode_exit(struct typec_altmode *altmode) header |= VDO_OPOS(altmode->mode); tcpm_queue_vdm(port, header, NULL, 0); - mod_delayed_work(port->wq, &port->vdm_state_machine, 0); mutex_unlock(&port->lock); return 0; @@ -1542,7 +1538,6 @@ static int tcpm_altmode_vdm(struct typec_altmode *altmode, mutex_lock(&port->lock); tcpm_queue_vdm(port, header, data, count - 1); - mod_delayed_work(port->wq, &port->vdm_state_machine, 0); mutex_unlock(&port->lock); return 0; From patchwork Wed Jul 15 13:22:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11665341 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C2A9314E3 for ; Wed, 15 Jul 2020 13:23:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AAF75206E9 for ; Wed, 15 Jul 2020 13:23:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="LolSOQML" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731730AbgGONXP (ORCPT ); Wed, 15 Jul 2020 09:23:15 -0400 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:59747 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731635AbgGONXO (ORCPT ); Wed, 15 Jul 2020 09:23:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1594819392; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7CNemoFdpI+ZQzM8HgdvQ4GtzyMtmS4KO3dG49C8x+E=; b=LolSOQMLqJRVFKtqktaSWAThTjCBGbQ1KVODzha4Hp2d89BIcT1FgEBiy0G02SvOpOCL0Q FkphtYkMlo95bMnzQE+kg43FF1eH2QdyNR+XMt73jK28DEp8lrKXYms+Mzo4MKVACoC3yP hIrMiX/k2J6uAy9KxhvNnsLpsIGmZhQ= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-441-c_pPjoycNjmY1PfJ8ER91Q-1; Wed, 15 Jul 2020 09:23:08 -0400 X-MC-Unique: c_pPjoycNjmY1PfJ8ER91Q-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C40678014D4; Wed, 15 Jul 2020 13:23:06 +0000 (UTC) Received: from x1.localdomain.com (ovpn-113-224.ams2.redhat.com [10.36.113.224]) by smtp.corp.redhat.com (Postfix) with ESMTP id B1B6E60BF4; Wed, 15 Jul 2020 13:23:05 +0000 (UTC) From: Hans de Goede To: Greg Kroah-Hartman , Guenter Roeck , Heikki Krogerus Cc: Hans de Goede , linux-usb@vger.kernel.org Subject: [PATCH 2/6] usb: typec: tcpm: Move locking into tcpm_queue_vdm() Date: Wed, 15 Jul 2020 15:22:57 +0200 Message-Id: <20200715132301.99816-3-hdegoede@redhat.com> In-Reply-To: <20200715132301.99816-1-hdegoede@redhat.com> References: <20200715132301.99816-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Various callers (all the typec_altmode_ops) take the port-lock just for the tcpm_queue_vdm() call. Rename the raw (unlocked) tcpm_queue_vdm() call to tcpm_queue_vdm_unlocked() and add a new tcpm_queue_vdm() helper which takes the lock, so that its callers don't have to do this themselves. This is a preparation patch for fixing an AB BA lock inversion between the tcpm code and some altmode drivers. Signed-off-by: Hans de Goede --- drivers/usb/typec/tcpm/tcpm.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index fc6455a29c74..30e997d6ea1e 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -958,9 +958,11 @@ static void tcpm_queue_message(struct tcpm_port *port, /* * VDM/VDO handling functions */ -static void tcpm_queue_vdm(struct tcpm_port *port, const u32 header, - const u32 *data, int cnt) +static void tcpm_queue_vdm_unlocked(struct tcpm_port *port, const u32 header, + const u32 *data, int cnt) { + WARN_ON(!mutex_is_locked(&port->lock)); + port->vdo_count = cnt + 1; port->vdo_data[0] = header; memcpy(&port->vdo_data[1], data, sizeof(u32) * cnt); @@ -971,6 +973,14 @@ static void tcpm_queue_vdm(struct tcpm_port *port, const u32 header, mod_delayed_work(port->wq, &port->vdm_state_machine, 0); } +static void tcpm_queue_vdm(struct tcpm_port *port, const u32 header, + const u32 *data, int cnt) +{ + mutex_lock(&port->lock); + tcpm_queue_vdm_unlocked(port, header, data, cnt); + mutex_unlock(&port->lock); +} + static void svdm_consume_identity(struct tcpm_port *port, const __le32 *payload, int cnt) { @@ -1249,7 +1259,7 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port, rlen = tcpm_pd_svdm(port, payload, cnt, response); if (rlen > 0) - tcpm_queue_vdm(port, response[0], &response[1], rlen - 1); + tcpm_queue_vdm_unlocked(port, response[0], &response[1], rlen - 1); } static void tcpm_send_vdm(struct tcpm_port *port, u32 vid, int cmd, @@ -1263,7 +1273,7 @@ static void tcpm_send_vdm(struct tcpm_port *port, u32 vid, int cmd, /* set VDM header with VID & CMD */ header = VDO(vid, ((vid & USB_SID_PD) == USB_SID_PD) ? 1 : (PD_VDO_CMD(cmd) <= CMD_ATTENTION), cmd); - tcpm_queue_vdm(port, header, data, count); + tcpm_queue_vdm_unlocked(port, header, data, count); } static unsigned int vdm_ready_timeout(u32 vdm_hdr) @@ -1506,13 +1516,10 @@ static int tcpm_altmode_enter(struct typec_altmode *altmode, u32 *vdo) struct tcpm_port *port = typec_altmode_get_drvdata(altmode); u32 header; - mutex_lock(&port->lock); header = VDO(altmode->svid, vdo ? 2 : 1, CMD_ENTER_MODE); header |= VDO_OPOS(altmode->mode); tcpm_queue_vdm(port, header, vdo, vdo ? 1 : 0); - mutex_unlock(&port->lock); - return 0; } @@ -1521,13 +1528,10 @@ static int tcpm_altmode_exit(struct typec_altmode *altmode) struct tcpm_port *port = typec_altmode_get_drvdata(altmode); u32 header; - mutex_lock(&port->lock); header = VDO(altmode->svid, 1, CMD_EXIT_MODE); header |= VDO_OPOS(altmode->mode); tcpm_queue_vdm(port, header, NULL, 0); - mutex_unlock(&port->lock); - return 0; } @@ -1536,10 +1540,7 @@ static int tcpm_altmode_vdm(struct typec_altmode *altmode, { struct tcpm_port *port = typec_altmode_get_drvdata(altmode); - mutex_lock(&port->lock); tcpm_queue_vdm(port, header, data, count - 1); - mutex_unlock(&port->lock); - return 0; } From patchwork Wed Jul 15 13:22:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11665337 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 18AFE618 for ; Wed, 15 Jul 2020 13:23:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E5FC6206D5 for ; Wed, 15 Jul 2020 13:23:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="K4oJ3Q06" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731687AbgGONXN (ORCPT ); Wed, 15 Jul 2020 09:23:13 -0400 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:29482 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731443AbgGONXM (ORCPT ); Wed, 15 Jul 2020 09:23:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1594819391; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2UDDjRT5DTeodvdg9nAF2HaEUxsszK69GWVaPjWM178=; b=K4oJ3Q062S6G4E2N5hjrZ++pr3UoDglim+buR/hyxxzFRVBh8eUUIhEQ8YNhHXM60YvG9C paUObaNp6YLiNfiQMysaPbYQerC3/iABCZyE6/SaGEPZsqUPaTJj4bauCP0aU4ONL4PcLQ FpFb1EsBD5pnTyES//F85drB8YxVzI4= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-146-BEGA7h6CML6YswqtWKcdyg-1; Wed, 15 Jul 2020 09:23:09 -0400 X-MC-Unique: BEGA7h6CML6YswqtWKcdyg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 284341080; Wed, 15 Jul 2020 13:23:08 +0000 (UTC) Received: from x1.localdomain.com (ovpn-113-224.ams2.redhat.com [10.36.113.224]) by smtp.corp.redhat.com (Postfix) with ESMTP id 14FA7610AF; Wed, 15 Jul 2020 13:23:06 +0000 (UTC) From: Hans de Goede To: Greg Kroah-Hartman , Guenter Roeck , Heikki Krogerus Cc: Hans de Goede , linux-usb@vger.kernel.org Subject: [PATCH 3/6] usb: typec: tcpm: Refactor tcpm_handle_vdm_request payload handling Date: Wed, 15 Jul 2020 15:22:58 +0200 Message-Id: <20200715132301.99816-4-hdegoede@redhat.com> In-Reply-To: <20200715132301.99816-1-hdegoede@redhat.com> References: <20200715132301.99816-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Refactor the tcpm_handle_vdm_request payload handling by doing the endianness conversion only once directly inside tcpm_handle_vdm_request itself instead of doing it multiple times inside various helper functions called by tcpm_handle_vdm_request. This is a preparation patch for some further refactoring to fix an AB BA lock inversion between the tcpm code and some altmode drivers. Signed-off-by: Hans de Goede Reviewed-by: Guenter Roeck --- drivers/usb/typec/tcpm/tcpm.c | 49 ++++++++++++++++------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 30e997d6ea1e..bf5a0322dbfe 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -981,16 +981,15 @@ static void tcpm_queue_vdm(struct tcpm_port *port, const u32 header, mutex_unlock(&port->lock); } -static void svdm_consume_identity(struct tcpm_port *port, const __le32 *payload, - int cnt) +static void svdm_consume_identity(struct tcpm_port *port, const u32 *p, int cnt) { - u32 vdo = le32_to_cpu(payload[VDO_INDEX_IDH]); - u32 product = le32_to_cpu(payload[VDO_INDEX_PRODUCT]); + u32 vdo = p[VDO_INDEX_IDH]; + u32 product = p[VDO_INDEX_PRODUCT]; memset(&port->mode_data, 0, sizeof(port->mode_data)); port->partner_ident.id_header = vdo; - port->partner_ident.cert_stat = le32_to_cpu(payload[VDO_INDEX_CSTAT]); + port->partner_ident.cert_stat = p[VDO_INDEX_CSTAT]; port->partner_ident.product = product; typec_partner_set_identity(port->partner); @@ -1000,17 +999,15 @@ static void svdm_consume_identity(struct tcpm_port *port, const __le32 *payload, PD_PRODUCT_PID(product), product & 0xffff); } -static bool svdm_consume_svids(struct tcpm_port *port, const __le32 *payload, - int cnt) +static bool svdm_consume_svids(struct tcpm_port *port, const u32 *p, int cnt) { struct pd_mode_data *pmdata = &port->mode_data; int i; for (i = 1; i < cnt; i++) { - u32 p = le32_to_cpu(payload[i]); u16 svid; - svid = (p >> 16) & 0xffff; + svid = (p[i] >> 16) & 0xffff; if (!svid) return false; @@ -1020,7 +1017,7 @@ static bool svdm_consume_svids(struct tcpm_port *port, const __le32 *payload, pmdata->svids[pmdata->nsvids++] = svid; tcpm_log(port, "SVID %d: 0x%x", pmdata->nsvids, svid); - svid = p & 0xffff; + svid = p[i] & 0xffff; if (!svid) return false; @@ -1036,8 +1033,7 @@ static bool svdm_consume_svids(struct tcpm_port *port, const __le32 *payload, return false; } -static void svdm_consume_modes(struct tcpm_port *port, const __le32 *payload, - int cnt) +static void svdm_consume_modes(struct tcpm_port *port, const u32 *p, int cnt) { struct pd_mode_data *pmdata = &port->mode_data; struct typec_altmode_desc *paltmode; @@ -1054,7 +1050,7 @@ static void svdm_consume_modes(struct tcpm_port *port, const __le32 *payload, paltmode->svid = pmdata->svids[pmdata->svid_index]; paltmode->mode = i; - paltmode->vdo = le32_to_cpu(payload[i]); + paltmode->vdo = p[i]; tcpm_log(port, " Alternate mode %d: SVID 0x%04x, VDO %d: 0x%08x", pmdata->altmodes, paltmode->svid, @@ -1082,21 +1078,17 @@ static void tcpm_register_partner_altmodes(struct tcpm_port *port) #define supports_modal(port) PD_IDH_MODAL_SUPP((port)->partner_ident.id_header) -static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt, +static int tcpm_pd_svdm(struct tcpm_port *port, const u32 *p, int cnt, u32 *response) { struct typec_altmode *adev; struct typec_altmode *pdev; struct pd_mode_data *modep; - u32 p[PD_MAX_PAYLOAD]; int rlen = 0; int cmd_type; int cmd; int i; - for (i = 0; i < cnt; i++) - p[i] = le32_to_cpu(payload[i]); - cmd_type = PD_VDO_CMDT(p[0]); cmd = PD_VDO_CMD(p[0]); @@ -1157,13 +1149,13 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt, switch (cmd) { case CMD_DISCOVER_IDENT: /* 6.4.4.3.1 */ - svdm_consume_identity(port, payload, cnt); + svdm_consume_identity(port, p, cnt); response[0] = VDO(USB_SID_PD, 1, CMD_DISCOVER_SVID); rlen = 1; break; case CMD_DISCOVER_SVID: /* 6.4.4.3.2 */ - if (svdm_consume_svids(port, payload, cnt)) { + if (svdm_consume_svids(port, p, cnt)) { response[0] = VDO(USB_SID_PD, 1, CMD_DISCOVER_SVID); rlen = 1; @@ -1175,7 +1167,7 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt, break; case CMD_DISCOVER_MODES: /* 6.4.4.3.3 */ - svdm_consume_modes(port, payload, cnt); + svdm_consume_modes(port, p, cnt); modep->svid_index++; if (modep->svid_index < modep->nsvids) { u16 svid = modep->svids[modep->svid_index]; @@ -1238,15 +1230,18 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt, static void tcpm_handle_vdm_request(struct tcpm_port *port, const __le32 *payload, int cnt) { - int rlen = 0; + u32 p[PD_MAX_PAYLOAD]; u32 response[8] = { }; - u32 p0 = le32_to_cpu(payload[0]); + int i, rlen = 0; + + for (i = 0; i < cnt; i++) + p[i] = le32_to_cpu(payload[i]); if (port->vdm_state == VDM_STATE_BUSY) { /* If UFP responded busy retry after timeout */ - if (PD_VDO_CMDT(p0) == CMDT_RSP_BUSY) { + if (PD_VDO_CMDT(p[0]) == CMDT_RSP_BUSY) { port->vdm_state = VDM_STATE_WAIT_RSP_BUSY; - port->vdo_retry = (p0 & ~VDO_CMDT_MASK) | + port->vdo_retry = (p[0] & ~VDO_CMDT_MASK) | CMDT_INIT; mod_delayed_work(port->wq, &port->vdm_state_machine, msecs_to_jiffies(PD_T_VDM_BUSY)); @@ -1255,8 +1250,8 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port, port->vdm_state = VDM_STATE_DONE; } - if (PD_VDO_SVDM(p0)) - rlen = tcpm_pd_svdm(port, payload, cnt, response); + if (PD_VDO_SVDM(p[0])) + rlen = tcpm_pd_svdm(port, p, cnt, response); if (rlen > 0) tcpm_queue_vdm_unlocked(port, response[0], &response[1], rlen - 1); From patchwork Wed Jul 15 13:22:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11665343 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3E239618 for ; Wed, 15 Jul 2020 13:23:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1F9012071B for ; Wed, 15 Jul 2020 13:23:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="AJAiAoFr" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731674AbgGONXQ (ORCPT ); Wed, 15 Jul 2020 09:23:16 -0400 Received: from us-smtp-1.mimecast.com ([205.139.110.61]:49970 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731466AbgGONXO (ORCPT ); Wed, 15 Jul 2020 09:23:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1594819393; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IZORDFMpyEouFhz1Bt8G1EZjIt5BLlmJaP0huVnVmuo=; b=AJAiAoFrkM/LPWZI+3s43eH2knhh2xZMxtoo3pVSl1lUurFpm5dQz/AB+IqNcIcR5y8q2Q O1WWDI0Kbm0Om2MtgO2MzGWyS2VgwcLT4VyN8IW4aioRcemUqo3Orq/mJteoOQ+jydbWOT 0ZKD4yrNSJuhsfX9Msu/AWSKiFPZoCk= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-194-TX4fgRd7PJ-CLQrE7A-dRw-1; Wed, 15 Jul 2020 09:23:10 -0400 X-MC-Unique: TX4fgRd7PJ-CLQrE7A-dRw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7DD5480183C; Wed, 15 Jul 2020 13:23:09 +0000 (UTC) Received: from x1.localdomain.com (ovpn-113-224.ams2.redhat.com [10.36.113.224]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7051560BF4; Wed, 15 Jul 2020 13:23:08 +0000 (UTC) From: Hans de Goede To: Greg Kroah-Hartman , Guenter Roeck , Heikki Krogerus Cc: Hans de Goede , linux-usb@vger.kernel.org Subject: [PATCH 4/6] usb: typec: tcpm: Refactor tcpm_handle_vdm_request Date: Wed, 15 Jul 2020 15:22:59 +0200 Message-Id: <20200715132301.99816-5-hdegoede@redhat.com> In-Reply-To: <20200715132301.99816-1-hdegoede@redhat.com> References: <20200715132301.99816-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Refactor tcpm_handle_vdm_request and its tcpm_pd_svdm helper function so that reporting the results of the vdm to the altmode-driver is separated out into a clear separate step inside tcpm_handle_vdm_request, instead of being scattered over various places inside the tcpm_pd_svdm helper. This is a preparation patch for fixing an AB BA lock inversion between the tcpm code and some altmode drivers. Signed-off-by: Hans de Goede --- drivers/usb/typec/tcpm/tcpm.c | 80 +++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 31 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index bf5a0322dbfe..4745b4062000 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -159,6 +159,14 @@ enum pd_msg_request { PD_MSG_DATA_SOURCE_CAP, }; +enum adev_actions { + ADEV_NONE = 0, + ADEV_NOTIFY_USB_AND_QUEUE_VDM, + ADEV_QUEUE_VDM, + ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL, + ADEV_ATTENTION, +}; + /* Events from low level driver */ #define TCPM_CC_EVENT BIT(0) @@ -1079,9 +1087,8 @@ static void tcpm_register_partner_altmodes(struct tcpm_port *port) #define supports_modal(port) PD_IDH_MODAL_SUPP((port)->partner_ident.id_header) static int tcpm_pd_svdm(struct tcpm_port *port, const u32 *p, int cnt, - u32 *response) + u32 *response, enum adev_actions *adev_action) { - struct typec_altmode *adev; struct typec_altmode *pdev; struct pd_mode_data *modep; int rlen = 0; @@ -1097,9 +1104,6 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const u32 *p, int cnt, modep = &port->mode_data; - adev = typec_match_altmode(port->port_altmode, ALTMODE_DISCOVERY_MAX, - PD_VDO_VID(p[0]), PD_VDO_OPOS(p[0])); - pdev = typec_match_altmode(port->partner_altmode, ALTMODE_DISCOVERY_MAX, PD_VDO_VID(p[0]), PD_VDO_OPOS(p[0])); @@ -1125,8 +1129,7 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const u32 *p, int cnt, break; case CMD_ATTENTION: /* Attention command does not have response */ - if (adev) - typec_altmode_attention(adev, p[1]); + *adev_action = ADEV_ATTENTION; return 0; default: break; @@ -1178,27 +1181,18 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const u32 *p, int cnt, } break; case CMD_ENTER_MODE: - if (adev && pdev) { + if (pdev) typec_altmode_update_active(pdev, true); - if (typec_altmode_vdm(adev, p[0], &p[1], cnt)) { - response[0] = VDO(adev->svid, 1, - CMD_EXIT_MODE); - response[0] |= VDO_OPOS(adev->mode); - return 1; - } - } + *adev_action = ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL; return 0; case CMD_EXIT_MODE: - if (adev && pdev) { + if (pdev) typec_altmode_update_active(pdev, false); - /* Back to USB Operation */ - WARN_ON(typec_altmode_notify(adev, - TYPEC_STATE_USB, - NULL)); - } - break; + /* Back to USB Operation */ + *adev_action = ADEV_NOTIFY_USB_AND_QUEUE_VDM; + return 0; default: break; } @@ -1207,11 +1201,8 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const u32 *p, int cnt, switch (cmd) { case CMD_ENTER_MODE: /* Back to USB Operation */ - if (adev) - WARN_ON(typec_altmode_notify(adev, - TYPEC_STATE_USB, - NULL)); - break; + *adev_action = ADEV_NOTIFY_USB_AND_QUEUE_VDM; + return 0; default: break; } @@ -1221,15 +1212,15 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const u32 *p, int cnt, } /* Informing the alternate mode drivers about everything */ - if (adev) - typec_altmode_vdm(adev, p[0], &p[1], cnt); - + *adev_action = ADEV_QUEUE_VDM; return rlen; } static void tcpm_handle_vdm_request(struct tcpm_port *port, const __le32 *payload, int cnt) { + enum adev_actions adev_action = ADEV_NONE; + struct typec_altmode *adev; u32 p[PD_MAX_PAYLOAD]; u32 response[8] = { }; int i, rlen = 0; @@ -1237,6 +1228,9 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port, for (i = 0; i < cnt; i++) p[i] = le32_to_cpu(payload[i]); + adev = typec_match_altmode(port->port_altmode, ALTMODE_DISCOVERY_MAX, + PD_VDO_VID(p[0]), PD_VDO_OPOS(p[0])); + if (port->vdm_state == VDM_STATE_BUSY) { /* If UFP responded busy retry after timeout */ if (PD_VDO_CMDT(p[0]) == CMDT_RSP_BUSY) { @@ -1251,7 +1245,31 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port, } if (PD_VDO_SVDM(p[0])) - rlen = tcpm_pd_svdm(port, p, cnt, response); + rlen = tcpm_pd_svdm(port, p, cnt, response, &adev_action); + + if (adev) { + switch (adev_action) { + case ADEV_NONE: + break; + case ADEV_NOTIFY_USB_AND_QUEUE_VDM: + WARN_ON(typec_altmode_notify(adev, TYPEC_STATE_USB, NULL)); + typec_altmode_vdm(adev, p[0], &p[1], cnt); + break; + case ADEV_QUEUE_VDM: + typec_altmode_vdm(adev, p[0], &p[1], cnt); + break; + case ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL: + if (typec_altmode_vdm(adev, p[0], &p[1], cnt)) { + response[0] = VDO(adev->svid, 1, CMD_EXIT_MODE); + response[0] |= VDO_OPOS(adev->mode); + rlen = 1; + } + break; + case ADEV_ATTENTION: + typec_altmode_attention(adev, p[1]); + break; + } + } if (rlen > 0) tcpm_queue_vdm_unlocked(port, response[0], &response[1], rlen - 1); From patchwork Wed Jul 15 13:23:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11665345 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8BDCF1510 for ; Wed, 15 Jul 2020 13:23:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 73555206E9 for ; Wed, 15 Jul 2020 13:23:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="GGfuxse4" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731694AbgGONXQ (ORCPT ); Wed, 15 Jul 2020 09:23:16 -0400 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:55216 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731632AbgGONXP (ORCPT ); Wed, 15 Jul 2020 09:23:15 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1594819393; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2GHkjXa5QzjbUQ3/921CfjxB8LSwQlSmMfE01bQxcg4=; b=GGfuxse4brJbHi1P+h52YpTS877keLs9CmwyeN55Z3bPXeVyoETl1Z+4tBptZrUfap1juF 3RjnfaXPzeprYuCyig7a6UoOomVT4ZoWL0O40C0N81w6nV4HurPagfPeA/3/B/NJH7wL2J yXPcp77P0PstadiazfHmcQApz3F5jXM= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-362-HqqJBpSxOMKLP5nX3WF84A-1; Wed, 15 Jul 2020 09:23:11 -0400 X-MC-Unique: HqqJBpSxOMKLP5nX3WF84A-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D8AA3106B246; Wed, 15 Jul 2020 13:23:10 +0000 (UTC) Received: from x1.localdomain.com (ovpn-113-224.ams2.redhat.com [10.36.113.224]) by smtp.corp.redhat.com (Postfix) with ESMTP id C67B760BF4; Wed, 15 Jul 2020 13:23:09 +0000 (UTC) From: Hans de Goede To: Greg Kroah-Hartman , Guenter Roeck , Heikki Krogerus Cc: Hans de Goede , linux-usb@vger.kernel.org Subject: [PATCH 5/6] usb: typec: tcpm: Fix AB BA lock inversion between tcpm code and the alt-mode drivers Date: Wed, 15 Jul 2020 15:23:00 +0200 Message-Id: <20200715132301.99816-6-hdegoede@redhat.com> In-Reply-To: <20200715132301.99816-1-hdegoede@redhat.com> References: <20200715132301.99816-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org When we receive a PD data packet which ends up being for the alt-mode driver we have the following lock order: 1. tcpm_pd_rx_handler take the tcpm-port lock 2. We call into the alt-mode driver which takes the alt-mode's lock And when the alt-mode driver initiates communication we have the following lock order: 3. alt-mode driver takes the alt-mode's lock 4. alt-mode driver calls tcpm_altmode_enter which takes the tcpm-port lock This is a classic AB BA lock inversion issue. With the refactoring of tcpm_handle_vdm_request() done before this patch, we don't rely on, or need to make changes to the tcpm-port data by the time we make call 2. from above. All data to be passed to the alt-mode driver sits on our stack at this point, and thus does not need locking. So after the refactoring we can simply fix this by releasing the tcpm-port lock before calling into the alt-mode driver. This fixes the following lockdep warning: [ 191.454238] ====================================================== [ 191.454240] WARNING: possible circular locking dependency detected [ 191.454244] 5.8.0-rc5+ #1 Not tainted [ 191.454246] ------------------------------------------------------ [ 191.454248] kworker/u8:5/794 is trying to acquire lock: [ 191.454251] ffff9bac8e30d4a8 (&dp->lock){+.+.}-{3:3}, at: dp_altmode_vdm+0x30/0xf0 [typec_displayport] [ 191.454263] but task is already holding lock: [ 191.454264] ffff9bac9dc240a0 (&port->lock#2){+.+.}-{3:3}, at: tcpm_pd_rx_handler+0x43/0x12c0 [tcpm] [ 191.454273] which lock already depends on the new lock. [ 191.454275] the existing dependency chain (in reverse order) is: [ 191.454277] -> #1 (&port->lock#2){+.+.}-{3:3}: [ 191.454286] __mutex_lock+0x7b/0x820 [ 191.454290] tcpm_altmode_enter+0x23/0x90 [tcpm] [ 191.454293] dp_altmode_work+0xca/0xe0 [typec_displayport] [ 191.454299] process_one_work+0x23f/0x570 [ 191.454302] worker_thread+0x55/0x3c0 [ 191.454305] kthread+0x138/0x160 [ 191.454309] ret_from_fork+0x22/0x30 [ 191.454311] -> #0 (&dp->lock){+.+.}-{3:3}: [ 191.454317] __lock_acquire+0x1241/0x2090 [ 191.454320] lock_acquire+0xa4/0x3d0 [ 191.454323] __mutex_lock+0x7b/0x820 [ 191.454326] dp_altmode_vdm+0x30/0xf0 [typec_displayport] [ 191.454330] tcpm_pd_rx_handler+0x11ae/0x12c0 [tcpm] [ 191.454333] process_one_work+0x23f/0x570 [ 191.454336] worker_thread+0x55/0x3c0 [ 191.454338] kthread+0x138/0x160 [ 191.454341] ret_from_fork+0x22/0x30 [ 191.454343] other info that might help us debug this: [ 191.454345] Possible unsafe locking scenario: [ 191.454347] CPU0 CPU1 [ 191.454348] ---- ---- [ 191.454350] lock(&port->lock#2); [ 191.454353] lock(&dp->lock); [ 191.454355] lock(&port->lock#2); [ 191.454357] lock(&dp->lock); [ 191.454360] *** DEADLOCK *** Signed-off-by: Hans de Goede --- drivers/usb/typec/tcpm/tcpm.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 4745b4062000..ea14240423d1 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -1247,6 +1247,27 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port, if (PD_VDO_SVDM(p[0])) rlen = tcpm_pd_svdm(port, p, cnt, response, &adev_action); + /* + * We are done with any state stored in the port struct now, except + * for any port struct changes done by the tcpm_queue_vdm() call + * below, which is a separate operation. + * + * So we can safely release the lock here; and we MUST release the + * lock here to avoid an AB BA lock inversion: + * + * If we keep the lock here then the lock ordering in this path is: + * 1. tcpm_pd_rx_handler take the tcpm port lock + * 2. One of the typec_altmode_* calls below takes the alt-mode's lock + * + * And we also have this ordering: + * 1. alt-mode driver takes the alt-mode's lock + * 2. alt-mode driver calls tcpm_altmode_enter which takes the + * tcpm port lock + * + * Dropping our lock here avoids this. + */ + mutex_unlock(&port->lock); + if (adev) { switch (adev_action) { case ADEV_NONE: @@ -1272,7 +1293,15 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port, } if (rlen > 0) - tcpm_queue_vdm_unlocked(port, response[0], &response[1], rlen - 1); + tcpm_queue_vdm(port, response[0], &response[1], rlen - 1); + + /* + * We must re-take the lock here to balance the unlock in + * tcpm_pd_rx_handler, note that no changes are made while the lock + * is held again. All that is done is unwinding the call stack until + * we return to tcpm_pd_rx_handler and do the unlock there. + */ + mutex_lock(&port->lock); } static void tcpm_send_vdm(struct tcpm_port *port, u32 vid, int cmd, From patchwork Wed Jul 15 13:23:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11665347 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 16F01618 for ; Wed, 15 Jul 2020 13:23:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F0EC0206D5 for ; Wed, 15 Jul 2020 13:23:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="LPXq2qPw" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731721AbgGONXR (ORCPT ); Wed, 15 Jul 2020 09:23:17 -0400 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:31984 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731746AbgGONXQ (ORCPT ); Wed, 15 Jul 2020 09:23:16 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1594819394; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zSpluyUKdUG79URZIXyRyDsj8DWnJBiQ7uAkyeWNNOw=; b=LPXq2qPwdwj4MxZMbhsLj4VGg85uZ+4xvf6SVgVUqHfCgdyx/WMFasL3FYg8+O6vSlVe/n tIpJTG+BfYDDIgZTJF+uQrZxLqa+SloaPQPTh9sZMOM822m6jqrsHHaRh1yPkT7aZ0k/hI ETb3pqLny1tsNxKN/M8DAGwTPTRTiKk= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-232--LK6730_NdycayB6rBFl6A-1; Wed, 15 Jul 2020 09:23:13 -0400 X-MC-Unique: -LK6730_NdycayB6rBFl6A-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3AB3E1083; Wed, 15 Jul 2020 13:23:12 +0000 (UTC) Received: from x1.localdomain.com (ovpn-113-224.ams2.redhat.com [10.36.113.224]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2A3F160BF4; Wed, 15 Jul 2020 13:23:11 +0000 (UTC) From: Hans de Goede To: Greg Kroah-Hartman , Guenter Roeck , Heikki Krogerus Cc: Hans de Goede , linux-usb@vger.kernel.org Subject: [PATCH 6/6] usb: typec: tcpm: Add WARN_ON ensure we are not tryong to send 2 VDM packets at the same time Date: Wed, 15 Jul 2020 15:23:01 +0200 Message-Id: <20200715132301.99816-7-hdegoede@redhat.com> In-Reply-To: <20200715132301.99816-1-hdegoede@redhat.com> References: <20200715132301.99816-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org The tcpm.c code for sending VDMs assumes that there will only be one VDM in flight at the time. The "queue" used by tcpm_queue_vdm is only 1 entry deep. This assumes that the higher layers (tcpm state-machine and alt-mode drivers) ensure that queuing a new VDM before the old one has been completely send (or it timed out) add a WARN_ON to check for this. Signed-off-by: Hans de Goede --- drivers/usb/typec/tcpm/tcpm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index ea14240423d1..5adc30666566 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -971,6 +971,9 @@ static void tcpm_queue_vdm_unlocked(struct tcpm_port *port, const u32 header, { WARN_ON(!mutex_is_locked(&port->lock)); + /* Make sure we are not still processing a previous VDM packet */ + WARN_ON(port->vdm_state > VDM_STATE_DONE); + port->vdo_count = cnt + 1; port->vdo_data[0] = header; memcpy(&port->vdo_data[1], data, sizeof(u32) * cnt);