Received: by 2002:a25:f815:0:0:0:0:0 with SMTP id u21csp4135993ybd; Tue, 25 Jun 2019 14:56:45 -0700 (PDT) X-Google-Smtp-Source: APXvYqz9ihTJFKyt4LehKevE/LlDfPEW+HV7CX65176UM2pMwuCvGAmfNixmjK5+T0E+yE5RU2ws X-Received: by 2002:a17:90a:fa12:: with SMTP id cm18mr65651pjb.137.1561499805709; Tue, 25 Jun 2019 14:56:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561499805; cv=none; d=google.com; s=arc-20160816; b=nH52mJFx5+F1OWtqsy8kWO1tXv4yIzfINl7Qk/7mm9uGq93xkszt5u8356C+OIk74F Cweqceq7jcYjFDQv3DdLiVgmfRHC3W0I71kdIS7zX7RQnY0m+B1k0s1ymPe6fKBajp8i 9mCllRlvHNT71LnAARtZ94iLdssW9wy4D3Vsu6rzItiw6N9z61/NJtHUVtSJw2EMES6K qJoYvkNvCvSwbCMk5+JMKGLCxGvEzPNycmTgOtj3Lbe/IPj+XA+Ch8L36I8Q6xjzCCvu kg3tpgf+f3niRu6qKzulCtIf69CI/wx1PYSAGooVjegnTJThZkQCbPFrkgHoejEp4i97 CjUg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=vsGWDFoWq4uZ/izmiqzm3s9U3XUZ/ujUeAWfcSTnPsI=; b=WMaH9AshxAzApd7OZn85873+7iYrpx8zvKKLKxvhb7nDmwNPPuu3nk5jrBY687iUt5 ha5t0msD2tSSM+SvKJsJg0K/sZO/lQcjeST9guMILYFYO3DBjIxUfRY7oyc0B1c8TCeP 6iwAx0laVCHhVjfkEmWDodQ6A/ni14k4EBgkJjJ1bYHKyl2SRY9h86JE4m9tuxA+LhRH kMT+OIZwdVyhS4Iwr1uR1dokZsv1YlmmNSihIeQS8w/+K7Xc17hdOUaFBKRHdYfs0p6C MK0cRr0uJCU4qb9BHQau71ePmsFjQKmwDVO/lHo9Esh8MR/mC/HOjVGuAGRrvYa7IcBP 9i+w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=UesSR29a; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l13si29973pjq.69.2019.06.25.14.56.29; Tue, 25 Jun 2019 14:56:45 -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; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=UesSR29a; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726549AbfFYVyg (ORCPT + 99 others); Tue, 25 Jun 2019 17:54:36 -0400 Received: from mail-pg1-f196.google.com ([209.85.215.196]:42219 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725914AbfFYVyg (ORCPT ); Tue, 25 Jun 2019 17:54:36 -0400 Received: by mail-pg1-f196.google.com with SMTP id k13so94530pgq.9 for ; Tue, 25 Jun 2019 14:54:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=vsGWDFoWq4uZ/izmiqzm3s9U3XUZ/ujUeAWfcSTnPsI=; b=UesSR29a5IFIuc0hyMCBgsdCpOxynypkCiFRqYozIgNG/K/lWoaIv8Q0k5evk2YCOg a7x2+Wfn2fpF+ZZzuk1XBLAkUF94JvNMR6wnfMrzpOYgARROrAjfxTtBXD9VflGseCh0 RVUqMA8jClZ+MVwTPckC253koxYm9b1uT7WJ0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=vsGWDFoWq4uZ/izmiqzm3s9U3XUZ/ujUeAWfcSTnPsI=; b=lCTjyoR/rwAh7EAaTnjPfu+Hw18BhY0sFfahhDYzS2l38G5UAT1VtZOpFlsV6fq9GC zQ1bMvAbtsLBoOBKaFw6Ud9JkcyPsR+c/kQybdnQ0hqREYF/z0OhykW5gEEO+FmqZRSY q0zLDBGrpqf37rj83FmFY/EVm3TL1c88hjmZ2D0MPtGP3KpbZqv1VifysscZcvL3HMPE jY9r/NHoYdRAFZgaA6fCnpkwbx1rjKGUMulDv1XFvQMUsWpxetLjxMfe3Fq0gMKC07U2 Qm2Tb2qRTBWnfrd2g27pvmkB9CDNgix5mvLD07DMXE4xDH+RiYh+6QX9Ffxt0xRMBHez BFIw== X-Gm-Message-State: APjAAAWantkFhAG7OuVhcUtrzbHYGfZt8ARqic2JxyAAF1/fUt1lXM74 Uli/LnG4llup/adVNT6zLybEsA== X-Received: by 2002:a63:1322:: with SMTP id i34mr41786825pgl.424.1561499674675; Tue, 25 Jun 2019 14:54:34 -0700 (PDT) Received: from evgreen2.mtv.corp.google.com ([2620:15c:202:201:ffda:7716:9afc:1301]) by smtp.gmail.com with ESMTPSA id w22sm16669343pfi.175.2019.06.25.14.54.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 25 Jun 2019 14:54:34 -0700 (PDT) From: Evan Green To: Takashi Iwai Cc: Evan Green , Jaroslav Kysela , alsa-devel@alsa-project.org, =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= , linux-kernel@vger.kernel.org, Thomas Gleixner , Greg Kroah-Hartman Subject: [PATCH] ALSA: hda: Use correct start/count for sysfs init Date: Tue, 25 Jun 2019 14:54:18 -0700 Message-Id: <20190625215418.17548-1-evgreen@chromium.org> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The normal flow through the widget sysfs codepath is that snd_hdac_refresh_widgets() is called once without the sysfs bool set to set up codec->num_nodes and friends, then another time with the bool set to actually allocate all the sysfs widgets. However, during the first time allocation, hda_widget_sysfs_reinit() ignores the new num_nodes passed in via parameter and just calls hda_widget_sysfs_init(), using whatever was in codec->num_nodes before the update. This is not correct in cases where num_nodes changes. Here's an example: Sometime earlier: snd_hdac_refresh_widgets(hdac, false) sets codec->num_nodes to 2, widgets is still not allocated Now: snd_hdac_refresh_widgets(hdac, true) hda_widget_sysfs_reinit(num_nodes=7) hda_widget_sysfs_init() widget_tree_create() alloc(codec->num_nodes) // this is still 2 codec->num_nodes = 7 Pass num_nodes and start_nid down into widget_tree_create() so that the right number of nodes are allocated in all cases. Signed-off-by: Evan Green --- sound/hda/hdac_device.c | 2 +- sound/hda/hdac_sysfs.c | 14 ++++++++------ sound/hda/local.h | 3 ++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c index 6907dbefd08c..5e74acf45c81 100644 --- a/sound/hda/hdac_device.c +++ b/sound/hda/hdac_device.c @@ -144,7 +144,7 @@ int snd_hdac_device_register(struct hdac_device *codec) if (err < 0) return err; mutex_lock(&codec->widget_lock); - err = hda_widget_sysfs_init(codec); + err = hda_widget_sysfs_init(codec, codec->start_nid, codec->num_nodes); mutex_unlock(&codec->widget_lock); if (err < 0) { device_del(&codec->dev); diff --git a/sound/hda/hdac_sysfs.c b/sound/hda/hdac_sysfs.c index 909d5ef1179c..1c4b98929d9c 100644 --- a/sound/hda/hdac_sysfs.c +++ b/sound/hda/hdac_sysfs.c @@ -358,7 +358,8 @@ static int add_widget_node(struct kobject *parent, hda_nid_t nid, return 0; } -static int widget_tree_create(struct hdac_device *codec) +static int widget_tree_create(struct hdac_device *codec, + hda_nid_t start_nid, int num_nodes) { struct hdac_widget_tree *tree; int i, err; @@ -372,12 +373,12 @@ static int widget_tree_create(struct hdac_device *codec) if (!tree->root) return -ENOMEM; - tree->nodes = kcalloc(codec->num_nodes + 1, sizeof(*tree->nodes), + tree->nodes = kcalloc(num_nodes + 1, sizeof(*tree->nodes), GFP_KERNEL); if (!tree->nodes) return -ENOMEM; - for (i = 0, nid = codec->start_nid; i < codec->num_nodes; i++, nid++) { + for (i = 0, nid = start_nid; i < num_nodes; i++, nid++) { err = add_widget_node(tree->root, nid, &widget_node_group, &tree->nodes[i]); if (err < 0) @@ -396,14 +397,15 @@ static int widget_tree_create(struct hdac_device *codec) } /* call with codec->widget_lock held */ -int hda_widget_sysfs_init(struct hdac_device *codec) +int hda_widget_sysfs_init(struct hdac_device *codec, + hda_nid_t start_nid, int num_nodes) { int err; if (codec->widgets) return 0; /* already created */ - err = widget_tree_create(codec); + err = widget_tree_create(codec, start_nid, num_nodes); if (err < 0) { widget_tree_free(codec); return err; @@ -428,7 +430,7 @@ int hda_widget_sysfs_reinit(struct hdac_device *codec, int i; if (!codec->widgets) - return hda_widget_sysfs_init(codec); + return hda_widget_sysfs_init(codec, start_nid, num_nodes); tree = kmemdup(codec->widgets, sizeof(*tree), GFP_KERNEL); if (!tree) diff --git a/sound/hda/local.h b/sound/hda/local.h index 877631e39373..8936120ab4d9 100644 --- a/sound/hda/local.h +++ b/sound/hda/local.h @@ -28,7 +28,8 @@ static inline unsigned int get_wcaps_channels(u32 wcaps) } extern const struct attribute_group *hdac_dev_attr_groups[]; -int hda_widget_sysfs_init(struct hdac_device *codec); +int hda_widget_sysfs_init(struct hdac_device *codec, + hda_nid_t start_nid, int num_nodes); int hda_widget_sysfs_reinit(struct hdac_device *codec, hda_nid_t start_nid, int num_nodes); void hda_widget_sysfs_exit(struct hdac_device *codec); -- 2.20.1