Received: by 10.213.65.68 with SMTP id h4csp1057438imn; Thu, 22 Mar 2018 14:21:49 -0700 (PDT) X-Google-Smtp-Source: AG47ELvxxiOtBPuTCgHJzOOOxO8olaSNyig5wFWCJK1BYqL2xa2jVxkbIPm0YzdxOZ29J/5h/JEP X-Received: by 2002:a17:902:3041:: with SMTP id u59-v6mr5365595plb.208.1521753709897; Thu, 22 Mar 2018 14:21:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521753709; cv=none; d=google.com; s=arc-20160816; b=bdOr5Nmz8rUXolSY17OWmGZ0gmk6Rt5MewwCduYOhB+7jyUXB2A2BhX8ksGT5HXE5n 9kkDVQnNxq/iGH8ZDHjjww7VPV13HwZwPHDaq0I72me5LQAnwJ6G/IDV1sA8d+jG5Rf8 FqBVnXBFZ5UM2u5v58HM73nu6DR+Jwc1BmK4nTmrSOJi04oRfaXSCy+Jg9Ti9JZNZ3aZ xcuqp+d/zELwKlgT9YiaikVcxHBArQ11/TMxKexf9ZceftaYn6GQi4VciTLhLH30UlvV E000pVHPQkalpZWPC78ujxwHvmMLZakl0TKInlcjiC9ZdxaBIjbUMzGA4LGSCjWsfc17 rTDQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-language :content-transfer-encoding:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature :arc-authentication-results; bh=5jV7ypaCQZfCiZD50B64jSPi1r5y5gEcVyqXab1jFJY=; b=jMehOdM82gUgrLfxhep2HFb2PbrIyP8TxIEXjQNb3HY5TLAaZsdquat3nDpBqPPhQI 3IjHkqjdZM0fIPMHKCqxK01SsS1zJ6UiJMZo5Kqs6Up8+uA10mzVM3MGytMEMpvM7Uiy Yi11h/rdEtHvs7FYsDX2XIgpBnnMrw+YeTOH7Jsp7Cu7L03U1cFJYyVoWz4h7xGvMuZ2 aZBIq983K46YHr2JBxB0kbIV/ltRQkh21cryZfJ/SVWANhE1LHyaBFnQb4sIS0odGj3a P3AnUwSmQMpMvENH0jlavduF6oZ2UssOYRa95df3i/jctavLJpjL1A261aAfWij3x1Jm 2/dQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=tq+zJJZV; 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=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m9-v6si6844128plk.464.2018.03.22.14.21.33; Thu, 22 Mar 2018 14:21:49 -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=@gmail.com header.s=20161025 header.b=tq+zJJZV; 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=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751797AbeCVVUg (ORCPT + 99 others); Thu, 22 Mar 2018 17:20:36 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:37186 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751541AbeCVVUe (ORCPT ); Thu, 22 Mar 2018 17:20:34 -0400 Received: by mail-wm0-f65.google.com with SMTP id 139so130220wmn.2 for ; Thu, 22 Mar 2018 14:20:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-transfer-encoding:content-language; bh=5jV7ypaCQZfCiZD50B64jSPi1r5y5gEcVyqXab1jFJY=; b=tq+zJJZVSWPwnpjYDohWwM1eHOmRdjA2uV8Cb6Muy//wmjb6BPYD9fBKBYDolAey0f UiEdbw6Hy/oRLTHbJUnbvrIYjlQbYoTCRH4RwHw4LBmNraKbg7NuY6NJSwk+iwxREOWQ 2IovKSMHN2JNUKEFPDLCeaZLU9zNMzeOchA24Iy3W2Q2dsXwOnkwO7X+noOI9AmvsnAT 0jMXMVfkLGfVmkKTwRLNbR2FhLewta1DIJ+mfNWkarS/7zzs+qaXTnsQxr/wlvka4swp SyDPjlQWk0LOXpAHt9kEKBVLWy1GK5YgZmW6Q+cttX2OuP2lewE+8vWnS3u2q+bntGW0 TEPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=5jV7ypaCQZfCiZD50B64jSPi1r5y5gEcVyqXab1jFJY=; b=aI7xgbncz+8rkuzg1v/4PqhGyHUGD6QpHE/2O+vHtwJeWammRXFtH3rgC6GY24vNrR Pef7swVe0A9xySIEh7jYE2LKtZCLlOWIgveToXYNZet1liBI0u4bpVaswcxHTJBA60sC khkc5ZYq5Evp2HKmh9YBWMZ5D4RIzs0/QgBXT3m85ovWD3lvylTCGuuFO3IJcgTPRkaN to8WmuGdfEgln7W34KSpHbQ5zgEoX7qQWcWfGgjjqgb1OupO8R75mZAlxXU1my8vkkPV HJ1idk5SEAzrUyXbw1E2ItxewN7XwxWMkDmq57u8BkNwSKok9U1W8DBHxYYR16Tx80Z1 3e7Q== X-Gm-Message-State: AElRT7HCRJQrjOl2xqn0/8bS+eqpKgbhez4mtLrG8eEiu4lX01t0x8RE IVg5QIEglTi82oqhLCE7sl3Rmtd8xLc= X-Received: by 10.80.215.138 with SMTP id w10mr10852460edi.10.1521753632584; Thu, 22 Mar 2018 14:20:32 -0700 (PDT) Received: from [192.168.1.3] (x4dbaf46b.dyn.telefonica.de. [77.186.244.107]) by smtp.gmail.com with ESMTPSA id o61sm5453132edb.88.2018.03.22.14.20.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 22 Mar 2018 14:20:31 -0700 (PDT) Subject: Re: [PATCH v3] staging: bcm2835-audio: Release resources on module_exit() To: Andy Shevchenko Cc: Eric Anholt , Stefan Wahren , Greg Kroah-Hartman , Florian Fainelli , Ray Jui , Scott Branden , bcm-kernel-feedback-list , Michael Zoran , linux-rpi-kernel@lists.infradead.org, linux-arm Mailing List , devel@driverdev.osuosl.org, Linux Kernel Mailing List References: <15cc84cc-a887-7473-d64c-00c23e930e0d@gmail.com> <20180321184827.1043-1-k.marinushkin@gmail.com> From: Kirill Marinushkin Message-ID: Date: Thu, 22 Mar 2018 22:21:00 +0100 User-Agent: Mozilla/5.0 (X11; Linux i686; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Content-Language: en-US Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 03/21/18 20:24, Andy Shevchenko wrote: > On Wed, Mar 21, 2018 at 8:48 PM, Kirill Marinushkin > wrote: >> In the current implementation, `rmmod snd_bcm2835` does not release >> resources properly. It causes an oops when trying to list sound devices. >> >> This commit fixes it. >> >> The details WRT allocation / free are described below. >> >> Device structure WRT allocation: >> >> pdev >> \childdev[] >> \card >> \chip >> \pcm >> \ctl >> >> Allocation / register sequence: >> >> * childdev: devm_kzalloc - freed during driver detach >> * childdev: device_initialize - freed during device_unregister >> * pdev: devres_alloc - freed during driver detach >> * childdev: device_add - removed during device_unregister >> * pdev, childdev: devres_add - freed during driver detach >> * card: snd_card_new - freed during snd_card_free >> * chip: kzalloc - freed during kfree >> * card, chip: snd_device_new - freed during snd_device_free >> * chip: new_pcm - TODO: free pcm >> * chip: new_ctl - TODO: free ctl >> * card: snd_card_register - unregistered during snd_card_free >> >> Free / unregister sequence: >> >> * card: snd_card_free >> * card, chip: snd_device_free >> * childdev: device_unregister >> * chip: kfree >> >> Steps to reproduce the issue before this commit: >> >> ~~~~ >> $ rmmod snd_bcm2835 >> $ aplay -L >> [ 138.648130] Unable to handle kernel paging request at virtual address 7f1343c0 >> [ 138.660415] pgd = ad8f0000 >> [ 138.665567] [7f1343c0] *pgd=3864c811, *pte=00000000, *ppte=00000000 >> [ 138.674887] Internal error: Oops: 7 [#1] SMP ARM >> [ 138.683571] Modules linked in: sha256_generic cfg80211 rfkill snd_pcm snd_timer >> snd fixed uio_pdrv_genirq uio ip_tables x_tables ipv6 [last unloaded: snd_bcm2835 >> ] >> [ 138.706594] CPU: 3 PID: 463 Comm: aplay Tainted: G WC 4.15.0-rc1-v >> 7+ #6 >> [ 138.719833] Hardware name: BCM2835 >> [ 138.726016] task: b877ac00 task.stack: aebec000 >> [ 138.733408] PC is at try_module_get+0x38/0x24c >> [ 138.740813] LR is at snd_ctl_open+0x58/0x194 [snd] >> [ 138.748485] pc : [<801c4d5c>] lr : [<7f0e6b2c>] psr: 20000013 >> [ 138.757709] sp : aebedd60 ip : aebedd88 fp : aebedd84 >> [ 138.765884] r10: 00000000 r9 : 00000004 r8 : 7f0ed440 >> [ 138.774040] r7 : b7e469b0 r6 : 7f0e6b2c r5 : afd91900 r4 : 7f1343c0 >> [ 138.783571] r3 : aebec000 r2 : 00000001 r1 : b877ac00 r0 : 7f1343c0 >> [ 138.793084] Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user >> [ 138.803300] Control: 10c5387d Table: 2d8f006a DAC: 00000055 >> [ 138.812064] Process aplay (pid: 463, stack limit = 0xaebec210) >> [ 138.820868] Stack: (0xaebedd60 to 0xaebee000) >> [ 138.828207] dd60: 00000000 b848d000 afd91900 00000000 b7e469b0 7f0ed440 aebedda4 aebedd88 >> [ 138.842371] dd80: 7f0e6b2c 801c4d30 afd91900 7f0ea4dc 00000000 b7e469b0 aebeddcc aebedda8 >> [ 138.856611] dda0: 7f0e250c 7f0e6ae0 7f0e2464 b8478ec0 b7e469b0 afd91900 7f0ea388 00000000 >> [ 138.870864] ddc0: aebeddf4 aebeddd0 802ce590 7f0e2470 8090ab64 afd91900 afd91900 b7e469b0 >> [ 138.885301] dde0: afd91908 802ce4e4 aebede1c aebeddf8 802c57b4 802ce4f0 afd91900 aebedea8 >> [ 138.900110] de00: b7fa4c00 00000000 00000000 00000004 aebede3c aebede20 802c6ba8 802c56b4 >> [ 138.915260] de20: aebedea8 00000000 aebedf5c 00000000 aebedea4 aebede40 802d9a68 802c6b58 >> [ 138.930661] de40: b874ddd0 00000000 00000000 00000001 00000041 00000000 afd91900 aebede70 >> [ 138.946402] de60: 00000000 00000000 00000002 b7e469b0 b8a87610 b8d6ab80 801852f8 00080000 >> [ 138.962314] de80: aebedf5c aebedea8 00000001 80108464 aebec000 00000000 aebedf4c aebedea8 >> [ 138.978414] dea0: 802dacd4 802d970c b8a87610 b8d6ab80 a7982bc6 00000009 af363019 b9231480 >> [ 138.994617] dec0: 00000000 b8c038a0 b7e469b0 00000101 00000002 00000238 00000000 00000000 >> [ 139.010823] dee0: 00000000 aebedee8 00080000 0000000f aebedf3c aebedf00 802ed7e4 80843f94 >> [ 139.027025] df00: 00000003 00080000 b9231490 b9231480 00000000 00080000 af363000 00000000 >> [ 139.043229] df20: 00000005 00000002 ffffff9c 00000000 00080000 ffffff9c af363000 00000003 >> [ 139.059430] df40: aebedf94 aebedf50 802c6f70 802dac70 aebec000 00000000 00000001 00000000 >> [ 139.075629] df60: 00020000 00000004 00000100 00000001 7ebe577c 0002e038 00000000 00000005 >> [ 139.091828] df80: 80108464 aebec000 aebedfa4 aebedf98 802c7060 802c6e6c 00000000 aebedfa8 >> [ 139.108025] dfa0: 801082c0 802c7040 7ebe577c 0002e038 7ebe577c 00080000 00000b98 e81c8400 >> [ 139.124222] dfc0: 7ebe577c 0002e038 00000000 00000005 7ebe57e4 00a20af8 7ebe57f0 76f87394 >> [ 139.140419] dfe0: 00000000 7ebe55c4 76ec88e8 76df1d9c 60000010 7ebe577c 00000000 00000000 >> [ 139.156715] [<801c4d5c>] (try_module_get) from [<7f0e6b2c>] (snd_ctl_open+0x58/0x194 [snd]) >> [ 139.173222] [<7f0e6b2c>] (snd_ctl_open [snd]) from [<7f0e250c>] (snd_open+0xa8/0x14c [snd]) >> [ 139.189683] [<7f0e250c>] (snd_open [snd]) from [<802ce590>] (chrdev_open+0xac/0x188) >> [ 139.205465] [<802ce590>] (chrdev_open) from [<802c57b4>] (do_dentry_open+0x10c/0x314) >> [ 139.221347] [<802c57b4>] (do_dentry_open) from [<802c6ba8>] (vfs_open+0x5c/0x88) >> [ 139.236788] [<802c6ba8>] (vfs_open) from [<802d9a68>] (path_openat+0x368/0x944) >> [ 139.248270] [<802d9a68>] (path_openat) from [<802dacd4>] (do_filp_open+0x70/0xc4) >> [ 139.263731] [<802dacd4>] (do_filp_open) from [<802c6f70>] (do_sys_open+0x110/0x1d4) >> [ 139.279378] [<802c6f70>] (do_sys_open) from [<802c7060>] (SyS_open+0x2c/0x30) >> [ 139.290647] [<802c7060>] (SyS_open) from [<801082c0>] (ret_fast_syscall+0x0/0x28) >> [ 139.306021] Code: e3c3303f e5932004 e2822001 e5832004 (e5943000) >> [ 139.316265] ---[ end trace 7f3f7f6193b663ed ]--- >> [ 139.324956] note: aplay[463] exited with preempt_count 1 >> ~~~~ >> > Sorry, just noticed that devm part doesn't make sense after your patch > and misleading. > So, after addressing it, FWIW, > Reviewed-by: Andy Shevchenko I checked that actually devm makes sense and works as expected. I don't call snd_devm_release() manually, it is done by the devm resource management. So, the devm part does it's job correctly, that's why I will keep it as it is. Below is the backtrace, which demonstrates that devm does a proper automatic resource management. ~~~~ [  207.569694] [<7f12f04c>] (snd_devm_release [snd_bcm2835]) from [<805b5198>] (device_release+0x3c/0xa0) [  207.586486] [<805b5198>] (device_release) from [<8082abe4>] (kobject_put+0x94/0xf0) [  207.601569] [<8082abe4>] (kobject_put) from [<805b66a8>] (device_unregister+0x2c/0x30) [  207.616940] [<805b66a8>] (device_unregister) from [<7f12f09c>] (snd_devm_unregister_child+0x4c/0x5c [snd_bcm2835]) [  207.634965] [<7f12f09c>] (snd_devm_unregister_child [snd_bcm2835]) from [<805bda58>] (release_nodes+0x120/0x1e8) [  207.652930] [<805bda58>] (release_nodes) from [<805be55c>] (devres_release_all+0x40/0x5c) [  207.668825] [<805be55c>] (devres_release_all) from [<805baaf8>] (device_release_driver_internal+0x170/0x200) [  207.686573] [<805baaf8>] (device_release_driver_internal) from [<805babf4>] (driver_detach+0x48/0x7c) [  207.703887] [<805babf4>] (driver_detach) from [<805b9b88>] (bus_remove_driver+0x5c/0xb0) [  207.720063] [<805b9b88>] (bus_remove_driver) from [<805bb07c>] (driver_unregister+0x38/0x58) [  207.736660] [<805bb07c>] (driver_unregister) from [<805bc2f4>] (platform_driver_unregister+0x1c/0x20) [  207.754083] [<805bc2f4>] (platform_driver_unregister) from [<7f12f6fc>] (bcm2835_alsa_device_exit+0x1c/0x24 [snd_bcm2835]) [  207.773395] [<7f12f6fc>] (bcm2835_alsa_device_exit [snd_bcm2835]) from [<801c72b0>] (SyS_delete_module+0x17c/0x1d4) [  207.792066] [<801c72b0>] (SyS_delete_module) from [<801082c0>] (ret_fast_syscall+0x0/0x28) ~~~~ > P.S. I didn't get why do you need an empty ->remove() stub. Doesn't > work without it? I checked: it really works fine without the empty remove() function. I will get rid of it, and send the result as a patch v4. > >> Signed-off-by: Kirill Marinushkin >> Cc: Eric Anholt >> Cc: Stefan Wahren >> Cc: Greg Kroah-Hartman >> Cc: Florian Fainelli >> Cc: Ray Jui >> Cc: Scott Branden >> Cc: bcm-kernel-feedback-list@broadcom.com >> Cc: Michael Zoran >> Cc: linux-rpi-kernel@lists.infradead.org >> Cc: linux-arm-kernel@lists.infradead.org >> Cc: devel@driverdev.osuosl.org >> Cc: linux-kernel@vger.kernel.org >> --- >> .../staging/vc04_services/bcm2835-audio/bcm2835.c | 57 ++++++++++++---------- >> 1 file changed, 30 insertions(+), 27 deletions(-) >> >> diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c >> index 8f2d508183b2..125efc55ecb9 100644 >> --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c >> +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c >> @@ -36,6 +36,10 @@ MODULE_PARM_DESC(enable_compat_alsa, >> static void snd_devm_unregister_child(struct device *dev, void *res) >> { >> struct device *childdev = *(struct device **)res; >> + struct bcm2835_chip *chip = dev_get_drvdata(childdev); >> + struct snd_card *card = chip->card; >> + >> + snd_card_free(card); >> >> device_unregister(childdev); >> } >> @@ -61,6 +65,13 @@ static int snd_devm_add_child(struct device *dev, struct device *child) >> return 0; >> } >> >> +static void snd_devm_release(struct device *dev) >> +{ >> + struct bcm2835_chip *chip = dev_get_drvdata(dev); >> + >> + kfree(chip); >> +} >> + >> static struct device * >> snd_create_device(struct device *parent, >> struct device_driver *driver, >> @@ -76,6 +87,7 @@ snd_create_device(struct device *parent, >> device_initialize(device); >> device->parent = parent; >> device->driver = driver; >> + device->release = snd_devm_release; >> >> dev_set_name(device, "%s", name); >> >> @@ -86,18 +98,19 @@ snd_create_device(struct device *parent, >> return device; >> } >> >> -static int snd_bcm2835_free(struct bcm2835_chip *chip) >> -{ >> - kfree(chip); >> - return 0; >> -} >> - >> /* component-destructor >> * (see "Management of Cards and Components") >> */ >> static int snd_bcm2835_dev_free(struct snd_device *device) >> { >> - return snd_bcm2835_free(device->device_data); >> + struct bcm2835_chip *chip = device->device_data; >> + struct snd_card *card = chip->card; >> + >> + /* TODO: free pcm, ctl */ >> + >> + snd_device_free(card, chip); >> + >> + return 0; >> } >> >> /* chip-specific constructor >> @@ -122,7 +135,7 @@ static int snd_bcm2835_create(struct snd_card *card, >> >> err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); >> if (err) { >> - snd_bcm2835_free(chip); >> + kfree(chip); >> return err; >> } >> >> @@ -130,31 +143,14 @@ static int snd_bcm2835_create(struct snd_card *card, >> return 0; >> } >> >> -static void snd_devm_card_free(struct device *dev, void *res) >> -{ >> - struct snd_card *snd_card = *(struct snd_card **)res; >> - >> - snd_card_free(snd_card); >> -} >> - >> static struct snd_card *snd_devm_card_new(struct device *dev) >> { >> - struct snd_card **dr; >> struct snd_card *card; >> int ret; >> >> - dr = devres_alloc(snd_devm_card_free, sizeof(*dr), GFP_KERNEL); >> - if (!dr) >> - return ERR_PTR(-ENOMEM); >> - >> ret = snd_card_new(dev, -1, NULL, THIS_MODULE, 0, &card); >> - if (ret) { >> - devres_free(dr); >> + if (ret) >> return ERR_PTR(ret); >> - } >> - >> - *dr = card; >> - devres_add(dev, dr); >> >> return card; >> } >> @@ -313,7 +309,7 @@ static int snd_add_child_device(struct device *device, >> return err; >> } >> >> - dev_set_drvdata(child, card); >> + dev_set_drvdata(child, chip); >> dev_info(child, "card created with %d channels\n", numchans); >> >> return 0; >> @@ -414,6 +410,12 @@ static int snd_bcm2835_alsa_probe_dt(struct platform_device *pdev) >> return 0; >> } >> >> +static int snd_bcm2835_alsa_remove(struct platform_device *pdev) >> +{ >> + /* trigger snd_devm_unregister_child() */ >> + return 0; >> +} >> + >> #ifdef CONFIG_PM >> >> static int snd_bcm2835_alsa_suspend(struct platform_device *pdev, >> @@ -437,6 +439,7 @@ MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); >> >> static struct platform_driver bcm2835_alsa0_driver = { >> .probe = snd_bcm2835_alsa_probe_dt, >> + .remove = snd_bcm2835_alsa_remove, >> #ifdef CONFIG_PM >> .suspend = snd_bcm2835_alsa_suspend, >> .resume = snd_bcm2835_alsa_resume, >> -- >> 2.13.6 >> > >