From nobody Fri Nov 29 12:52:46 2024 Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 44EF819CD17 for ; Thu, 19 Sep 2024 13:51:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726753872; cv=none; b=JrNVSR3IriqEPHTK6C4hAoYhJ6ClgMIhXVU7G5kCFcTC9B9TjBRIY9wjs88b/AnPn9aDmUaZl2XBIiQgd46AcTAfqHL6Js7PdXqtUIaND0y0RRRBnA0qmNLWrJb8EB+w0JWCX4O8pBLYg6jXVqsoCi4TxQBJ3phPbVBmb1grvGM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726753872; c=relaxed/simple; bh=Kpz1+usHgjJU/8VmgUtQ8ArrQyQsIl8J4vMP1G7iaYY=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=NH+MrpU53k++J2jChsJwf6a2UnTKJWjT56ttZ0njV8AUiYkpeUuR8TBWnrUSMWCBeey0arxcGq1+w83HI2mIulEYHH6Vxp872q3tbN0oEjXBQLZ/2C8/NxG9V6g8kADNmMz4zDn2MzC6LeyM7+SL7t/rhyfvwciqaQjMa0zWLUQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=v4gZkMSE; arc=none smtp.client-ip=209.85.128.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="v4gZkMSE" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-42cba6cdf32so7418835e9.1 for ; Thu, 19 Sep 2024 06:51:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1726753868; x=1727358668; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=0PslU454aJ3lD1WuDQmVWdwungDho/+ZyzmQbd/e50g=; b=v4gZkMSE/8WW3/oskhlmt7GV1L4yKOMc2nkAntcV3yOmd4nC+DGTNDoaPELlKxO3XB 0VLi4wHEljPuYE4ynuVKJEfmtalPKLmVijM5NQwijH2Qmymwagnxz9R36q0YcwZF7i07 6ZHZOi1dBfFChs5cLXPR/9bPBYPjfmDIoJw4VxA7XSucFYfAYgDEcnGHb5xFaFBGydYK BBt76JilgpGP7WZ8Z9X+rPeH0jiHqyQPHUQNtdzTPiPr920iZA0JQA+9yZFqjYCX3BwI mqVNe62oB8yn1l9Pm8rVMevUDsoqnzgw2zj59WXMBeyYc7UlIfXetckR5cW1IPV5Qqsv Rzfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726753868; x=1727358668; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=0PslU454aJ3lD1WuDQmVWdwungDho/+ZyzmQbd/e50g=; b=KAd4YmddWKbD0ae0UJ023+YU7tKQyh1VOxUePvs4EflHK53FPLejzkq6VfgPnPHzB2 xKfIebYrnbs0PkkCvpYNSaQ9i99KIQLkqAthY+7dlj3ZONEVFTX+9Ln5yZ73zWPaowD1 sAOxc1iowfz01SwuOzSbgJg4YZ9acifaHvJwH7TMr57oN04IWboLH5L7oLJrvbqhWype M/0TPYpIW9v7KW68n4iKgRzlUjZRx/PKOav319pUtq+/gokv7E9wTCXRRSjWO7ZlYH5r mE2WTmiGQKmzipGNkr1rc8qq/vSxINcKApqtjI9bI9CTWO8Meey4xpami/JI88a8rwKH vTJw== X-Forwarded-Encrypted: i=1; AJvYcCX/ndsbjUHiNt559EZlWdqiyeAa+OIOnI+GaDCuTqOQdttWZ98bJXerTyN5iHbPwdbM+OjUr9GZBTbwfSo=@vger.kernel.org X-Gm-Message-State: AOJu0Yza4DL3wW8nad7ICwaD2PfllSmHl/uLGazGpJFsWXZtKwp/t2qz tvFDVIPLei4Jv1g5VvfKVBWmiiIIWoQO/4V2Qp2/HzfVkVbHsWPFnvhQoP0IheE= X-Google-Smtp-Source: AGHT+IHcEYpRlGgX+oWQx+eeC3m7K7Or5mirALPBtvRtHLw8dsmINQWFi4rbEZudPYl9jNXi14ScEQ== X-Received: by 2002:a05:600c:1c85:b0:42c:c003:edd8 with SMTP id 5b1f17b1804b1-42cdb531938mr208074395e9.6.1726753868332; Thu, 19 Sep 2024 06:51:08 -0700 (PDT) Received: from brgl-uxlite.. ([185.44.53.103]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42e75408abasm22767005e9.6.2024.09.19.06.51.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2024 06:51:07 -0700 (PDT) From: Bartosz Golaszewski To: Herve Codina , Linus Walleij Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Bartosz Golaszewski Subject: [PATCH v2] gpio: free irqs that are still requested when the chip is being removed Date: Thu, 19 Sep 2024 15:51:04 +0200 Message-ID: <20240919135104.3583-1-brgl@bgdev.pl> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Bartosz Golaszewski If we remove a GPIO chip that is also an interrupt controller with users not having freed some interrupts, we'll end up leaking resources as indicated by the following warning: remove_proc_entry: removing non-empty directory 'irq/30', leaking at leas= t 'gpio' As there's no way of notifying interrupt users about the irqchip going away and the interrupt subsystem is not plugged into the driver model and so not all cases can be handled by devlinks, we need to make sure to free all interrupts before the complete the removal of the provider. Signed-off-by: Bartosz Golaszewski Reviewed-by: Herve Codina Tested-by: Herve Codina --- v1 -> v2: - we should actually take the request_mutex to protect the irqaction from b= eing freed while we dereference it and keep the actual dereferencing under the= lock - add some comments to explain what we're doing drivers/gpio/gpiolib.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index c6afbf434366..16c16414f721 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -713,6 +714,45 @@ bool gpiochip_line_is_valid(const struct gpio_chip *gc, } EXPORT_SYMBOL_GPL(gpiochip_line_is_valid); =20 +static void gpiod_free_irqs(struct gpio_desc *desc) +{ + int irq =3D gpiod_to_irq(desc); + struct irq_desc *irqd =3D irq_to_desc(irq); + void *cookie; + + for (;;) { + /* + * Make sure the action doesn't go away while we're + * dereferencing it. Retrieve and store the cookie value. + * If the irq is freed after we release the lock, that's + * alright - the underlying maple tree lookup will return NULL + * and nothing will happen in free_irq(). + */ + scoped_guard(mutex, &irqd->request_mutex) { + if (!irq_desc_has_action(irqd)) + return; + + cookie =3D irqd->action->dev_id; + } + + free_irq(irq, cookie); + } +} + +/* + * The chip is going away but there may be users who had requested interru= pts + * on its GPIO lines who have no idea about its removal and have no way of + * being notified about it. We need to free any interrupts still in use he= re or + * we'll leak memory and resources (like procfs files). + */ +static void gpiochip_free_remaining_irqs(struct gpio_chip *gc) +{ + struct gpio_desc *desc; + + for_each_gpio_desc_with_flag(gc, desc, FLAG_USED_AS_IRQ) + gpiod_free_irqs(desc); +} + static void gpiodev_release(struct device *dev) { struct gpio_device *gdev =3D to_gpio_device(dev); @@ -1125,6 +1165,7 @@ void gpiochip_remove(struct gpio_chip *gc) /* FIXME: should the legacy sysfs handling be moved to gpio_device? */ gpiochip_sysfs_unregister(gdev); gpiochip_free_hogs(gc); + gpiochip_free_remaining_irqs(gc); =20 scoped_guard(mutex, &gpio_devices_lock) list_del_rcu(&gdev->list); --=20 2.30.2