Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp2658464pxj; Mon, 14 Jun 2021 04:14:06 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwJ1vN/kvSxoksOB1jsDDlGy3dx17MVQqwrefQaBAOL6KTGewxDDAX2SaNPcG27mYrJJylP X-Received: by 2002:a17:906:7f8d:: with SMTP id f13mr15026302ejr.272.1623669246789; Mon, 14 Jun 2021 04:14:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623669246; cv=none; d=google.com; s=arc-20160816; b=O8H2xpxjcuyMNPsW2ieV9t73xP9i2IoW1kXdRh5/oR7F8A4lpFIHF+QU+nmQfSITr/ lc6PrK3kNRvcThVh5+E9bpFwyqy4W1Z41SXvmrEywxzeFtvpFMlpzhcmiolzO7tmJw6x hsODedrnllPrRbchwPZ/Ocoa94yvIYLPCcTnvpkhMg8NFQ/5mGIjceaTUFBE+5xq0klp BlsSHqYZMNAeTLcfIwVv6RO3Jc4288+D7JC9xABe2Wu+ZYBEG/Du9R2H995Nh60sQk50 kgvTe2Qfw14N1O/BhXdmL1A/dz1N1uSPMYdtGe6zZ/s4UrPdZBv80esO9UnMddgkbLSF eXkQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=hmJfmOJI3oFzyYi/89kqMYn4rYM5M3aHvB7C7g0T7/w=; b=YkVyR3onGaGyKVYMNtuMzKffLeikpHSSgAGnzaJzHGEx4GdkOpoTTI+qMOXWQQsKcV q7jsIfu2QLSkP7CPDgxl0ZvlIkFhD3PGyV/pzSc2jg8yzI/c/yMi2ahmZ3QdwB2oQHT3 lzqPIwDiuseg8J21C4/FwDcdHLV5ljTXpKxoVXC1F1u9qT+tYrwXBg15BYHQ2biAficL uTpvplxT/223seOeTfKEvcb6l60bymJ62igroGfDmaJVI5DatYAZTtVH9k75s6x5EP+Z gU7S2zAEhqTe82rS74Q82+ioxIziOoaq+2nxJIhoKUDfrnkjh91zw16KkCoHsZz5y90E 4VCQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=ThRx4GL4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id w11si11614527edu.413.2021.06.14.04.13.44; Mon, 14 Jun 2021 04:14:06 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=ThRx4GL4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233085AbhFNLLz (ORCPT + 99 others); Mon, 14 Jun 2021 07:11:55 -0400 Received: from mail.kernel.org ([198.145.29.99]:36640 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235211AbhFNLA0 (ORCPT ); Mon, 14 Jun 2021 07:00:26 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 9A19961629; Mon, 14 Jun 2021 10:42:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1623667379; bh=9e+LP6ImzOzhs1q4SDn5l6/ZmimNdfb7PiDANUF2OK8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ThRx4GL4b2Qj1cQdxZEc+FtJRYn0CTklTZ/hUCXpFCdJwW8O/TQF7BfokB4lgjEB/ Ju+pdIlXOkD3q9K8kTkbHEzNJtDADAQthSJvR92CvD9vQJH+eGXu6gHIvTw2iTXUgW il7S1KfrrEE8bMfgc+9P2YGfGMnSRQSXVSgJP5mk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Saravana Kannan , Mark Brown , Sasha Levin Subject: [PATCH 5.10 004/131] spi: Fix spi device unregister flow Date: Mon, 14 Jun 2021 12:26:05 +0200 Message-Id: <20210614102653.118436524@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210614102652.964395392@linuxfoundation.org> References: <20210614102652.964395392@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Saravana Kannan [ Upstream commit c7299fea67696db5bd09d924d1f1080d894f92ef ] When an SPI device is unregistered, the spi->controller->cleanup() is called in the device's release callback. That's wrong for a couple of reasons: 1. spi_dev_put() can be called before spi_add_device() is called. And it's spi_add_device() that calls spi_setup(). This will cause clean() to get called without the spi device ever being setup. 2. There's no guarantee that the controller's driver would be present by the time the spi device's release function gets called. 3. It also causes "sleeping in atomic context" stack dump[1] when device link deletion code does a put_device() on the spi device. Fix these issues by simply moving the cleanup from the device release callback to the actual spi_unregister_device() function. [1] - https://lore.kernel.org/lkml/CAHp75Vc=FCGcUyS0v6fnxme2YJ+qD+Y-hQDQLa2JhWNON9VmsQ@mail.gmail.com/ Signed-off-by: Saravana Kannan Link: https://lore.kernel.org/r/20210426235638.1285530-1-saravanak@google.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index a6f1e94af13c..96560853b3a3 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -47,10 +47,6 @@ static void spidev_release(struct device *dev) { struct spi_device *spi = to_spi_device(dev); - /* spi controllers may cleanup for released devices */ - if (spi->controller->cleanup) - spi->controller->cleanup(spi); - spi_controller_put(spi->controller); kfree(spi->driver_override); kfree(spi); @@ -550,6 +546,12 @@ static int spi_dev_check(struct device *dev, void *data) return 0; } +static void spi_cleanup(struct spi_device *spi) +{ + if (spi->controller->cleanup) + spi->controller->cleanup(spi); +} + /** * spi_add_device - Add spi_device allocated with spi_alloc_device * @spi: spi_device to register @@ -614,11 +616,13 @@ int spi_add_device(struct spi_device *spi) /* Device may be bound to an active driver when this returns */ status = device_add(&spi->dev); - if (status < 0) + if (status < 0) { dev_err(dev, "can't add %s, status %d\n", dev_name(&spi->dev), status); - else + spi_cleanup(spi); + } else { dev_dbg(dev, "registered child %s\n", dev_name(&spi->dev)); + } done: mutex_unlock(&spi_add_lock); @@ -705,6 +709,8 @@ void spi_unregister_device(struct spi_device *spi) if (!spi) return; + spi_cleanup(spi); + if (spi->dev.of_node) { of_node_clear_flag(spi->dev.of_node, OF_POPULATED); of_node_put(spi->dev.of_node); -- 2.30.2