aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2015-07-27 00:34:50 -0400
committerMark Brown <broonie@kernel.org>2015-07-29 10:10:13 -0400
commit8ef9724bf9718af81cfc5132253372f79c71b7e2 (patch)
tree555b99af183bc6798d1b08b3f01f70d18b6eb3ba
parentd770e558e21961ad6cfdf0ff7df0eb5d7d4f0754 (diff)
regmap: regcache-rbtree: Clean new present bits on present bitmap resize
When inserting a new register into a block, the present bit map size is increased using krealloc. krealloc does not clear the additionally allocated memory, leaving it filled with random values. Result is that some registers are considered cached even though this is not the case. Fix the problem by clearing the additionally allocated memory. Also, if the bitmap size does not increase, do not reallocate the bitmap at all to reduce overhead. Fixes: 3f4ff561bc88 ("regmap: rbtree: Make cache_present bitmap per node") Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Mark Brown <broonie@kernel.org> Cc: stable@vger.kernel.org
-rw-r--r--drivers/base/regmap/regcache-rbtree.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index 81751a49d8bf..56486d92c4e7 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -296,11 +296,20 @@ static int regcache_rbtree_insert_to_block(struct regmap *map,
296 if (!blk) 296 if (!blk)
297 return -ENOMEM; 297 return -ENOMEM;
298 298
299 present = krealloc(rbnode->cache_present, 299 if (BITS_TO_LONGS(blklen) > BITS_TO_LONGS(rbnode->blklen)) {
300 BITS_TO_LONGS(blklen) * sizeof(*present), GFP_KERNEL); 300 present = krealloc(rbnode->cache_present,
301 if (!present) { 301 BITS_TO_LONGS(blklen) * sizeof(*present),
302 kfree(blk); 302 GFP_KERNEL);
303 return -ENOMEM; 303 if (!present) {
304 kfree(blk);
305 return -ENOMEM;
306 }
307
308 memset(present + BITS_TO_LONGS(rbnode->blklen), 0,
309 (BITS_TO_LONGS(blklen) - BITS_TO_LONGS(rbnode->blklen))
310 * sizeof(*present));
311 } else {
312 present = rbnode->cache_present;
304 } 313 }
305 314
306 /* insert the register value in the correct place in the rbnode block */ 315 /* insert the register value in the correct place in the rbnode block */