Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp1385101imm; Wed, 23 May 2018 15:22:21 -0700 (PDT) X-Google-Smtp-Source: AB8JxZqBVkMyEaZ67aCM/NUyG1Ps8J0kLxGNTgd7jmXGvSpHZQNiKV99p5eW1UaMukD+ppYZ5kTf X-Received: by 2002:a17:902:8bcb:: with SMTP id r11-v6mr4657489plo.51.1527114141061; Wed, 23 May 2018 15:22:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527114141; cv=none; d=google.com; s=arc-20160816; b=F5mA1R+9Zbj1TzYDl1sZRLwjT1qn087+74Iwth2yBOh57L32J1/tPzW7a/+aJq4NgK WF2tNoA4T6Px8wN8xmu84QbrunQ8pa/f7cO5O8tIKUPU+LMpoesAo4PZFV08XILVtXTo 5HgeMKNdsXaxoiKqK8QfvRy4pUXRSDMLTdU0Dj0X637PVUdL6ifcVpQ0jQQWBjRhYqRY WbjOCNFJ6APAarlnDgJT9m2PmkPQov3aP4UJUtXCR8pUlBrF6XmOUsVNp075M7iyLS3G 7RKFEklNa3itoJ8SyTAXrHGilX3QNAZ6e0Vf0wIL+10DiCla68ngzOk00bFlqQEplPJv PBJA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :arc-authentication-results; bh=vdNbBocA1FdDRzccTDQ06dQXIEm0Eo7TXwTyfmGOmH8=; b=bLvVDYJ5hrZjYVIZ5pOdn1AOM3IXZixcw9pLEqBTLYU/XzocrxE0bp4GcPit9SAvB8 PLdU/rNgpeWbHkmhtX73VxHZRhhWJLIthfxFcjz9JrvY6Z00MGMGwhlgSlNf7felzXG+ Ba7qgjJFH2imR9p13Exii6bkYnyj8nLquswRXfUTQt1Qcyuqqk6b7mfjcP6nPrBOUJcq Z9h5iEha6/ePyuJYEJUvkuZPu36j3YJ+cLNWk3fT7o4O0R28Y1C6cJCEmbSriHppJFfh YdJExFza22OdxqMW+65Qxl87OOtStDLwd6Si5JhJjFR3w5dYbUmL7bp7fhfgh4pwg1cC es4A== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q1-v6si19663772plb.549.2018.05.23.15.22.06; Wed, 23 May 2018 15:22:21 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934948AbeEWWVy (ORCPT + 99 others); Wed, 23 May 2018 18:21:54 -0400 Received: from mx2.suse.de ([195.135.220.15]:45607 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934486AbeEWWVw (ORCPT ); Wed, 23 May 2018 18:21:52 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 2E9A0AE6C; Wed, 23 May 2018 22:21:51 +0000 (UTC) From: Luis Henriques To: Jacek Anaszewski , Pavel Machek Cc: linux-leds@vger.kernel.org, linux-kernel@vger.kernel.org, Luis Henriques Subject: [PATCH] leds: class: ensure workqueue is initialized before setting brightness Date: Wed, 23 May 2018 23:22:21 +0100 Message-Id: <20180523222221.27621-1-lhenriques@suse.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org An application can try to set brightness before all the initialization is done, in particular before the workqueue is initialized with the call to led_init_core(). Here's a WARNING easy to trigger: [ 36.780813] WARNING: CPU: 3 PID: 1411 at ../kernel/workqueue.c:1444 __queue_work+0x37b/0x420 [ 36.780815] Modules linked in: ... [ 36.780868] CPU: 3 PID: 1411 Comm: systemd-backlig Not tainted 4.16.9-1-default #1 openSUSE Tumbleweed (unreleased) [ 36.780868] Hardware name: Dell Inc. Precision 5510/0N8J4R, BIOS 1.6.1 12/11/2017 [ 36.780870] RIP: 0010:__queue_work+0x37b/0x420 [ 36.780871] RSP: 0018:ffffaced048b7d78 EFLAGS: 00010086 [ 36.780873] RAX: 0000000000000000 RBX: ffffffffb3f01440 RCX: 0000000000000000 [ 36.780873] RDX: ffffffffc05a90d8 RSI: 0000000000000000 RDI: ffff8eac7dce2700 [ 36.780874] RBP: ffff8ea547c16400 R08: ffff8ea547800000 R09: ffff8eac7dc22700 [ 36.780875] R10: 0000000000000000 R11: 0000000000000040 R12: 0000000000000003 [ 36.780876] R13: 0000000000000200 R14: ffffffffc05a90d0 R15: ffff8eac7dce8600 [ 36.780877] FS: 00007f871e61cf40(0000) GS:ffff8eac7dcc0000(0000) knlGS:0000000000000000 [ 36.780878] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 36.780879] CR2: 000055c91115e308 CR3: 0000000883ee0005 CR4: 00000000003606e0 [ 36.780880] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 36.780880] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 36.780881] Call Trace: [ 36.780886] queue_work_on+0x81/0x90 [ 36.780889] brightness_store+0x5d/0x90 [ 36.780892] kernfs_fop_write+0x105/0x180 [ 36.780894] __vfs_write+0x26/0x150 [ 36.780897] ? common_file_perm+0x51/0x150 [ 36.780900] ? security_file_permission+0x3c/0xb0 [ 36.780901] vfs_write+0xad/0x1a0 [ 36.780903] SyS_write+0x42/0x90 [ 36.780906] do_syscall_64+0x76/0x140 [ 36.780908] entry_SYSCALL_64_after_hwframe+0x42/0xb7 [ 36.780910] RIP: 0033:0x7f871dd04c94 [ 36.780910] RSP: 002b:00007ffeb3a57d38 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 [ 36.780912] RAX: ffffffffffffffda RBX: 000055c91115c810 RCX: 00007f871dd04c94 [ 36.780912] RDX: 0000000000000001 RSI: 000055c91115c810 RDI: 0000000000000004 [ 36.780913] RBP: 00007ffeb3a57e10 R08: 0000000000000003 R09: 0000000000000000 [ 36.780914] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001 [ 36.780914] R13: 000055c911158f30 R14: 000055c90f3a9a4e R15: 0000000000000004 [ 36.780917] Code: 74 18 e8 49 80 00 00 48 85 c0 74 0e 48 8b 40 20 48 3b 68 08 0f 84 c2 fc ff ff 0f 0b 48 83 c4 10 5b 5d 41 5c 41 5d 41 5e 41 5f c3 <0f> 0b e9 82 fd ff ff 83 cd 02 49 8d 57 60 e9 69 fd ff ff 80 3d [ 36.780942] ---[ end trace 1fce4edad54c4017 ]--- This patch initializes and acquires the led_access mutex early in the of_led_classdev_register function, so that any application trying to write to sysfs to set brightness will block until initialization ends. Signed-off-by: Luis Henriques --- drivers/leds/led-class.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index b0e2d55acbd6..3c7e3487b373 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -260,10 +260,14 @@ int of_led_classdev_register(struct device *parent, struct device_node *np, if (ret < 0) return ret; + mutex_init(&led_cdev->led_access); + mutex_lock(&led_cdev->led_access); led_cdev->dev = device_create_with_groups(leds_class, parent, 0, led_cdev, led_cdev->groups, "%s", name); - if (IS_ERR(led_cdev->dev)) + if (IS_ERR(led_cdev->dev)) { + mutex_unlock(&led_cdev->led_access); return PTR_ERR(led_cdev->dev); + } led_cdev->dev->of_node = np; if (ret) @@ -274,6 +278,7 @@ int of_led_classdev_register(struct device *parent, struct device_node *np, ret = led_add_brightness_hw_changed(led_cdev); if (ret) { device_unregister(led_cdev->dev); + mutex_unlock(&led_cdev->led_access); return ret; } } @@ -285,7 +290,6 @@ int of_led_classdev_register(struct device *parent, struct device_node *np, #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED led_cdev->brightness_hw_changed = -1; #endif - mutex_init(&led_cdev->led_access); /* add to the list of leds */ down_write(&leds_list_lock); list_add_tail(&led_cdev->node, &leds_list); @@ -302,6 +306,8 @@ int of_led_classdev_register(struct device *parent, struct device_node *np, led_trigger_set_default(led_cdev); #endif + mutex_unlock(&led_cdev->led_access); + dev_dbg(parent, "Registered led device: %s\n", led_cdev->name);