lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240822-b4-regmap-maple-nolock-v1-5-d5e6dbae3396@kernel.org>
Date: Thu, 22 Aug 2024 20:13:39 +0100
From: Mark Brown <broonie@...nel.org>
To: "Liam R. Howlett" <Liam.Howlett@...cle.com>
Cc: Cristian Ciocaltea <cristian.ciocaltea@...labora.com>, 
 maple-tree@...ts.infradead.org, linux-mm@...ck.org, 
 linux-kernel@...r.kernel.org, Mark Brown <broonie@...nel.org>
Subject: [PATCH 5/5] regmap: Don't double lock maple cache when using a
 regmap provided lock

It is not possible to use the maple tree without holding a lock of some
kind, by default the maple tree incorporates a lock but it does have
support for registering an external lock which will be asserted against
instead. At present regmap uses the maple tree's internal lock which is
unfortunate since there is also regmap level locking above the cache which
protects the cache data structure and things like read/modify/write
operations.

Let's reduce the overhead here by telling the maple tree about the regmap
level lock for cases where regmap does it's own locking. We also support
external and custom locking for regmap, neither of which will benefit from
this, but this will cover the vast majority of users.

Signed-off-by: Mark Brown <broonie@...nel.org>
---
 drivers/base/regmap/internal.h       | 12 ++++++++++++
 drivers/base/regmap/regcache-maple.c |  9 +++++++++
 drivers/base/regmap/regmap.c         |  4 ++++
 3 files changed, 25 insertions(+)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 83acccdc1008..a5fe052a70ce 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -59,6 +59,9 @@ struct regmap {
 			unsigned long raw_spinlock_flags;
 		};
 	};
+#ifdef CONFIG_LOCKDEP
+	struct lockdep_map *lockdep;
+#endif
 	regmap_lock lock;
 	regmap_unlock unlock;
 	void *lock_arg; /* This is passed to lock/unlock functions */
@@ -344,4 +347,13 @@ struct regmap *__regmap_init_raw_ram(struct device *dev,
 #define regmap_init_raw_ram(dev, config, data)				\
 	__regmap_lockdep_wrapper(__regmap_init_raw_ram, #dev, dev, config, data)
 
+#ifdef CONFIG_LOCKDEP
+static inline void regmap_set_lockdep(struct regmap *m, struct lockdep_map *l)
+{
+	m->lockdep = l;
+}
+#else
+#define regmap_set_lockdep(m, l)
+#endif
+
 #endif
diff --git a/drivers/base/regmap/regcache-maple.c b/drivers/base/regmap/regcache-maple.c
index d2de3eba1646..1247ff3ae397 100644
--- a/drivers/base/regmap/regcache-maple.c
+++ b/drivers/base/regmap/regcache-maple.c
@@ -365,7 +365,16 @@ static int regcache_maple_init(struct regmap *map)
 		return -ENOMEM;
 	map->cache = mt;
 
+#ifdef CONFIG_LOCKDEP
+	if (map->lockdep) {
+		mt_init_flags(mt, MT_FLAGS_LOCK_EXTERN);
+		mt_set_external_lock_dep_map(mt, map->lockdep);
+	} else {
+		mt_init(mt);
+	}
+#else
 	mt_init(mt);
+#endif
 
 	if (!map->num_reg_defaults)
 		return 0;
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 9ed842d17642..f66b5ef56cf8 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -729,12 +729,15 @@ struct regmap *__regmap_init(struct device *dev,
 				map->unlock = regmap_unlock_raw_spinlock;
 				lockdep_set_class_and_name(&map->raw_spinlock,
 							   lock_key, lock_name);
+				regmap_set_lockdep(map,
+						   &map->raw_spinlock.dep_map);
 			} else {
 				spin_lock_init(&map->spinlock);
 				map->lock = regmap_lock_spinlock;
 				map->unlock = regmap_unlock_spinlock;
 				lockdep_set_class_and_name(&map->spinlock,
 							   lock_key, lock_name);
+				regmap_set_lockdep(map, &map->spinlock.dep_map);
 			}
 		} else {
 			mutex_init(&map->mutex);
@@ -743,6 +746,7 @@ struct regmap *__regmap_init(struct device *dev,
 			map->can_sleep = true;
 			lockdep_set_class_and_name(&map->mutex,
 						   lock_key, lock_name);
+			regmap_set_lockdep(map, &map->mutex.dep_map);
 		}
 		map->lock_arg = map;
 	}

-- 
2.39.2


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ