Skip to contentSkip to conversation

PM / OPP: fix debugfs files for 64-bit

PATCH In review Arnd Bergmann 6 participants 19 messages Oct 7, 2015 – Oct 20, 2015

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 PM / OPP: fix debugfs files for 64-bit

The recently added debugfs support for OPP creates files using the debugfs_create_bool() and debugfs_create_u32() interfaces, but casts the data argument to u32*, which is broken on some architectures.

In case of debugfs_create_bool(), the API has changed as of 621a5f7ad9cd ("debugfs: Pass bool pointer to debugfs_create_bool()"), so we now get a warning about the new interface in linux-next, which contains both patches. Removing the cast makes it work in linux-next, and makes it warn in cases where it does not work.

For debugfs_create_u32(), the current usage is broken on 64-bit architectures when the values exceed the range of 32-bit variables (which should not happen), or when the kernel is built for as big-endian. This patch removes the casts and changes the types to u32 to make them match and print the correct value on all architectures.

Fixes 5cb5fdbf38770 ("PM / OPP: Add debugfs support")

---
Found while building ARM allmodconfig

drivers/base/power/opp/core.c +3 -3
index 25f3efef24db..1cbc0acf831a 100644
@@ -696,7 +696,7 @@ static int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
 			break;
 
 		/* Duplicate OPPs */
-		dev_warn(dev, "%s: duplicate OPPs detected. Existing: freq: %lu, volt: %lu, enabled: %d. New: freq: %lu, volt: %lu, enabled: %d\n",
+		dev_warn(dev, "%s: duplicate OPPs detected. Existing: freq: %u, volt: %u, enabled: %d. New: freq: %u, volt: %u, enabled: %d\n",
 			 __func__, opp->rate, opp->u_volt, opp->available,
 			 new_opp->rate, new_opp->u_volt, new_opp->available);
 
@@ -898,7 +898,7 @@ static int _opp_add_static_v2(struct device *dev, struct device_node *np)
 	/* OPP to select on device suspend */
 	if (of_property_read_bool(np, "opp-suspend")) {
 		if (dev_opp->suspend_opp)
-			dev_warn(dev, "%s: Multiple suspend OPPs found (%lu %lu)\n",
+			dev_warn(dev, "%s: Multiple suspend OPPs found (%u %u)\n",
 				 __func__, dev_opp->suspend_opp->rate,
 				 new_opp->rate);
 		else
@@ -910,7 +910,7 @@ static int _opp_add_static_v2(struct device *dev, struct device_node *np)
 
 	mutex_unlock(&dev_opp_list_lock);
 
-	pr_debug("%s: turbo:%d rate:%lu uv:%lu uvmin:%lu uvmax:%lu latency:%lu\n",
+	pr_debug("%s: turbo:%d rate:%u uv:%u uvmin:%u uvmax:%u latency:%u\n",
 		 __func__, new_opp->turbo, new_opp->rate, new_opp->u_volt,
 		 new_opp->u_volt_min, new_opp->u_volt_max,
 		 new_opp->clock_latency_ns);
drivers/base/power/opp/debugfs.c +10 -11
index 865cbfa24640..45436dabae8d 100644
@@ -38,43 +38,42 @@ int opp_debug_create_one(struct dev_pm_opp *opp, struct device_opp *dev_opp)
 	char name[15];
 
 	/* Rate is unique to each OPP, use it to give opp-name */
-	sprintf(name, "opp:%lu", opp->rate);
+	sprintf(name, "opp:%u", opp->rate);
 
 	/* Create per-opp directory */
 	d = debugfs_create_dir(name, pdentry);
 	if (!d)
 		return -ENOMEM;
 
-	if (!debugfs_create_bool("available", S_IRUGO, d,
-				 (u32 *)&opp->available))
+	if (!debugfs_create_bool("available", S_IRUGO, d, &opp->available))
 		return -ENOMEM;
 
-	if (!debugfs_create_bool("dynamic", S_IRUGO, d, (u32 *)&opp->dynamic))
+	if (!debugfs_create_bool("dynamic", S_IRUGO, d, &opp->dynamic))
 		return -ENOMEM;
 
-	if (!debugfs_create_bool("turbo", S_IRUGO, d, (u32 *)&opp->turbo))
+	if (!debugfs_create_bool("turbo", S_IRUGO, d, &opp->turbo))
 		return -ENOMEM;
 
-	if (!debugfs_create_u32("rate_hz", S_IRUGO, d, (u32 *)&opp->rate))
+	if (!debugfs_create_u32("rate_hz", S_IRUGO, d, &opp->rate))
 		return -ENOMEM;
 
 	if (!debugfs_create_u32("u_volt_target", S_IRUGO, d,
-				(u32 *)&opp->u_volt))
+				&opp->u_volt))
 		return -ENOMEM;
 
 	if (!debugfs_create_u32("u_volt_min", S_IRUGO, d,
-				(u32 *)&opp->u_volt_min))
+				&opp->u_volt_min))
 		return -ENOMEM;
 
 	if (!debugfs_create_u32("u_volt_max", S_IRUGO, d,
-				(u32 *)&opp->u_volt_max))
+				&opp->u_volt_max))
 		return -ENOMEM;
 
-	if (!debugfs_create_u32("u_amp", S_IRUGO, d, (u32 *)&opp->u_amp))
+	if (!debugfs_create_u32("u_amp", S_IRUGO, d, &opp->u_amp))
 		return -ENOMEM;
 
 	if (!debugfs_create_u32("clock_latency_ns", S_IRUGO, d,
-				(u32 *)&opp->clock_latency_ns))
+				&opp->clock_latency_ns))
 		return -ENOMEM;
 
 	opp->dentry = d;
drivers/base/power/opp/opp.h +6 -6
index 0e4c27fb0c4a..ef573e650773 100644
@@ -71,13 +71,13 @@ struct dev_pm_opp {
 	bool available;
 	bool dynamic;
 	bool turbo;
-	unsigned long rate;
+	u32 rate;
 
-	unsigned long u_volt;
-	unsigned long u_volt_min;
-	unsigned long u_volt_max;
-	unsigned long u_amp;
-	unsigned long clock_latency_ns;
+	u32 u_volt;
+	u32 u_volt_min;
+	u32 u_volt_max;
+	u32 u_amp;
+	u32 clock_latency_ns;
 
 	struct device_opp *dev_opp;
 	struct rcu_head rcu_head;
#1 lore raw

Hi Arnd,

Quoted 17 lines · Arnd Bergmann

The recently added debugfs support for OPP creates files using the debugfs_create_bool() and debugfs_create_u32() interfaces, but casts the data argument to u32*, which is broken on some architectures.

In case of debugfs_create_bool(), the API has changed as of 621a5f7ad9cd ("debugfs: Pass bool pointer to debugfs_create_bool()"), so we now get a warning about the new interface in linux-next, which contains both patches. Removing the cast makes it work in linux-next, and makes it warn in cases where it does not work.

For debugfs_create_u32(), the current usage is broken on 64-bit architectures when the values exceed the range of 32-bit variables (which should not happen), or when the kernel is built for as big-endian. This patch removes the casts and changes the types to u32 to make them match and print the correct value on all architectures.

Quoted 4 lines
Fixes 5cb5fdbf38770 ("PM / OPP: Add debugfs support")

---
Found while building ARM allmodconfig

Thanks. I just got back from vacations and this was the first thing I was going to look at. :)

So, there are two problems here and I feel they should be fixed separately.

The bool thing is simple to fix, just remove the cast as you did. Though it will keep warning if we use pm/linux-next branch directly, but will work well with linux-next.

The second problem isn't that trivial. Just making unsigned longs as u32 doesn't look like the right solution to me (at least). They are unsigned long, to match the expected types with other frameworks like clock and regulator.

What about adding something like debugfs_create_unsigned_long() for such cases?

@Greg ??

Signature · 1 line
viresh
#2 lore raw
Quoted 2 lines · Viresh Kumar

What about adding something like debugfs_create_unsigned_long() for such cases?

And that can be as simple (or ugly, not sure if its buggy) as:

debugfs_create_unsigned_long()

{
        if (sizeof(unsigned long) == sizeof(u32))
                return debugfs_create_u32();
        if (sizeof(unsigned long) == sizeof(u64))
                return debugfs_create_u64();

        return -EINVAL;
}
Signature · 1 line
viresh
#3 lore raw
Quoted 7 lines · Viresh Kumar
Quoted 2 lines · Viresh Kumar

What about adding something like debugfs_create_unsigned_long() for such cases?

And that can be as simple (or ugly, not sure if its buggy) as:

debugfs_create_unsigned_long()

Quoted 8 lines
{
        if (sizeof(unsigned long) == sizeof(u32))
                return debugfs_create_u32();
        if (sizeof(unsigned long) == sizeof(u64))
                return debugfs_create_u64();

        return -EINVAL;
}

Why would you be wanting to create a "unsigned long" as an api anyway? Just force it to be u64 all the time, can't you do that?

thanks,

greg k-h

#4 lore raw
Quoted 2 lines · Greg Kroah-Hartman

Why would you be wanting to create a "unsigned long" as an api anyway? Just force it to be u64 all the time, can't you do that?

Okay, so the variable in question (lets say frequency) is an 'unsigned long' and that's how all the APIs of clock framework expect/define it.

And you are probably saying that we do this:

unsigned long freq;

debugfs_create_u64((u64 *)&freq);

Right? Or are you asking to update clock APIs to be converted to u64?

This will break things on a 32 bit architecture where unsigned long is 32 bits long, as doing this will overwrite the next 32 bits:

*freq = XYZ;

Signature · 1 line
viresh
#5 lore raw
Quoted 8 lines · Viresh Kumar
Quoted 2 lines · Greg Kroah-Hartman

Why would you be wanting to create a "unsigned long" as an api anyway? Just force it to be u64 all the time, can't you do that?

Okay, so the variable in question (lets say frequency) is an 'unsigned long' and that's how all the APIs of clock framework expect/define it.

Quoted 7 lines

And you are probably saying that we do this:

unsigned long freq;

debugfs_create_u64((u64 *)&freq);

Right? Or are you asking to update clock APIs to be converted to u64?

Yes, they should be u64 as I doubt you want to debug problems that you have in the driver where it works on a 64bit system but doesn't on a 32bit one.

thanks,

greg k-h

#6 lore raw

Cc'ing Mike and Stephen..

Quoted 13 lines · Greg Kroah-Hartman
Quoted 12 lines · Viresh Kumar
Quoted 2 lines · Greg Kroah-Hartman

Why would you be wanting to create a "unsigned long" as an api anyway? Just force it to be u64 all the time, can't you do that?

Okay, so the variable in question (lets say frequency) is an 'unsigned long' and that's how all the APIs of clock framework expect/define it.

And you are probably saying that we do this:

unsigned long freq;

Quoted 7 lines
Quoted 3 lines

debugfs_create_u64((u64 *)&freq);

Right? Or are you asking to update clock APIs to be converted to u64?

Yes, they should be u64 as I doubt you want to debug problems that you have in the driver where it works on a 64bit system but doesn't on a 32bit one.

Firstly changing the clock API (and other similar APIs) to make frequency u64 instead of 'unsigned long', looks like a giant effort. There are too many users of those API, etc..

Over that, it might be good performance wise to use u32 for 32 bit systems and u64 for 64 bit one, to represent clock frequency and maybe that's why we chose unsigned long there.

Signature · 1 line
viresh
#7 lore raw
Quoted 24 lines · Viresh Kumar

Cc'ing Mike and Stephen..

Quoted 13 lines · Greg Kroah-Hartman
Quoted 12 lines · Viresh Kumar
Quoted 2 lines · Greg Kroah-Hartman

Why would you be wanting to create a "unsigned long" as an api anyway? Just force it to be u64 all the time, can't you do that?

Okay, so the variable in question (lets say frequency) is an 'unsigned long' and that's how all the APIs of clock framework expect/define it.

And you are probably saying that we do this:

unsigned long freq;

Quoted 7 lines
Quoted 3 lines

debugfs_create_u64((u64 *)&freq);

Right? Or are you asking to update clock APIs to be converted to u64?

Yes, they should be u64 as I doubt you want to debug problems that you have in the driver where it works on a 64bit system but doesn't on a 32bit one.

Quoted 7 lines

Firstly changing the clock API (and other similar APIs) to make frequency u64 instead of 'unsigned long', looks like a giant effort. There are too many users of those API, etc..

Over that, it might be good performance wise to use u32 for 32 bit systems and u64 for 64 bit one, to represent clock frequency and maybe that's why we chose unsigned long there.

Ok, then stop exporting it in debugfs and everyone will be happy :)

greg k-h

#8 lore raw
Quoted 1 line · Greg Kroah-Hartman

Ok, then stop exporting it in debugfs and everyone will be happy :)

Hehe, not really. See I am not happy :(

So, what do you suggest? Should we create debugfs_create_ulong()? And how to implement that? With existing u32/u64 APIs or from scratch?

Signature · 1 line
viresh
#9 lore raw
Quoted 4 lines · Viresh Kumar
Quoted 1 line · Greg Kroah-Hartman

Ok, then stop exporting it in debugfs and everyone will be happy :)

Hehe, not really. See I am not happy :(

Why not? Why does this have to be exported in debugfs? Just delete it, who cares about it? It's just "debugging".

Quoted 1 line

So, what do you suggest? Should we create debugfs_create_ulong()?

Ick, do we _really_ need and want that?

Quoted 1 line

And how to implement that? With existing u32/u64 APIs or from scratch?

It's probably easy to just do in a few lines "from scratch", if you really need/want it, right?

thanks,

greg k-h

#10 lore raw
Quoted 2 lines · Greg Kroah-Hartman

Why not? Why does this have to be exported in debugfs? Just delete it, who cares about it? It's just "debugging".

It is really useful to see all the freq/voltage combinations on which a device can work on, specially the CPU. And there are some serious users of it as well..

Android has hacked the cpufreq layer today, to export something similar in a hacky way, as they wanted to estimate power ratings based on Hz/uV values. This will kill them as well..

And its really useful for debugging as well, to see if all went well.

Maybe debugfs is not really the best place for this, but yeah, this is very useful.

Signature · 1 line
viresh
#11 lore raw
In reply to Viresh Kumar
Quoted 24 lines · On Wednesday 07 October 2015 18:33:24 Viresh Kumar wrote:

Cc'ing Mike and Stephen..

Quoted 13 lines · Greg Kroah-Hartman
Quoted 12 lines · Viresh Kumar
Quoted 2 lines · Greg Kroah-Hartman

Why would you be wanting to create a "unsigned long" as an api anyway? Just force it to be u64 all the time, can't you do that?

Okay, so the variable in question (lets say frequency) is an 'unsigned long' and that's how all the APIs of clock framework expect/define it.

And you are probably saying that we do this:

unsigned long freq;

Quoted 7 lines
Quoted 3 lines

debugfs_create_u64((u64 *)&freq);

Right? Or are you asking to update clock APIs to be converted to u64?

Yes, they should be u64 as I doubt you want to debug problems that you have in the driver where it works on a 64bit system but doesn't on a 32bit one.

Quoted 7 lines

Firstly changing the clock API (and other similar APIs) to make frequency u64 instead of 'unsigned long', looks like a giant effort. There are too many users of those API, etc..

Over that, it might be good performance wise to use u32 for 32 bit systems and u64 for 64 bit one, to represent clock frequency and maybe that's why we chose unsigned long there.

I think it clearly makes sense to have a fixed length for each of these
members: either 32 bit is enough to represent all possible values, then there is no need to make them 'long' on 64-bit architectures, or 32 bit is not enough and then the code is broken on 32-bit architectures today and should be fixed.

In my patch, I assumed that if 32-bit architectures work fine today, then we don't need more range on 64-bit architectures either.

Arnd

#12 lore raw
Quoted 7 lines · Arnd Bergmann

I think it clearly makes sense to have a fixed length for each of these members:

either 32 bit is enough to represent all possible values, then there is no need to make them 'long' on 64-bit architectures, or 32 bit is not enough and then the code is broken on 32-bit architectures today and should be fixed.

I agree.

But I am not 100% sure why it was done this way to start with. Probably this is the logic behind that:
- Max clock rate supported by a u32 is ~ 4.295 GHz
- People expected that, we will not reach this rate for 32 bit systems but for 64 bit ones.
- If above is true, then making it u64 for all will generate not very optimized code for 32bit systems, as we need to fetch two 32bit values everytime then.
- And making it u32 for 64 bit systems wouldn't be great as well, as we need to mask out half of the read value.

Ofcourse, Mike and Stephen can correct me here :)

Quoted 2 lines

In my patch, I assumed that if 32-bit architectures work fine today, then we don't need more range on 64-bit architectures either.

The problem here is that we haven't fixed it properly.
- clock framework expects it to be unsigned long
- DT is sending a 64 bit value in Hz
- But we are storing and exposing it in u32

That's weird, isn't it?

So, either we update clock API and other similar APIs to u64 or u32 (which may not be the right thing to do), Or we keep it unsigned long here as well and add debugfs_create_ulong().

Signature · 1 line
viresh
#13 lore raw
Quoted 8 lines · Viresh Kumar
Quoted 2 lines

In my patch, I assumed that if 32-bit architectures work fine today, then we don't need more range on 64-bit architectures either.

The problem here is that we haven't fixed it properly.
- clock framework expects it to be unsigned long
- DT is sending a 64 bit value in Hz
- But we are storing and exposing it in u32

Quoted 5 lines

That's weird, isn't it?

So, either we update clock API and other similar APIs to u64 or u32 (which may not be the right thing to do), Or we keep it unsigned long here as well and add debugfs_create_ulong().

I don't see why debugfs can't accomodate C's builtin types, rather than insisting on predetermined sizes. After, the printf family of functions does that: %u vs. %lu. In fact, there's no way to tell printf that a particular value is 32 bits or 64 bits.

Alan Stern

#14 lore raw
In reply to Viresh Kumar

Quoting Viresh Kumar (2015-10-08 00:48:28)

Quoted 22 lines · Arnd Bergmann
Quoted 7 lines

I think it clearly makes sense to have a fixed length for each of these members:

either 32 bit is enough to represent all possible values, then there is no need to make them 'long' on 64-bit architectures, or 32 bit is not enough and then the code is broken on 32-bit architectures today and should be fixed.

I agree.

But I am not 100% sure why it was done this way to start with. Probably this is the logic behind that:
- Max clock rate supported by a u32 is ~ 4.295 GHz
- People expected that, we will not reach this rate for 32 bit systems but for 64 bit ones.
- If above is true, then making it u64 for all will generate not very optimized code for 32bit systems, as we need to fetch two 32bit values everytime then.
- And making it u32 for 64 bit systems wouldn't be great as well, as we need to mask out half of the read value.

Quoted 1 line

Ofcourse, Mike and Stephen can correct me here :)

I chose unsigned long for the common clock framework _implemenation_, because the long-standing clk.h _api_ returns this type for clk_get_rate and passes this type in for clk_set_rate and clk_round_rate.

Quoted 8 lines
Quoted 3 lines

In my patch, I assumed that if 32-bit architectures work fine today, then we don't need more range on 64-bit architectures either.

The problem here is that we haven't fixed it properly.
- clock framework expects it to be unsigned long
- DT is sending a 64 bit value in Hz
- But we are storing and exposing it in u32

Don't forget cpufreq is using unsigned int for KHz.

Quoted 2 lines

That's weird, isn't it?

Yes it is.

Quoted 4 lines

So, either we update clock API and other similar APIs to u64 or u32 (which may not be the right thing to do), Or we keep it unsigned long here as well and add debugfs_create_ulong().

This comes up every now and then. I'm still trying to figure out if sub-Hertz quantities should be considered (e.g. representing freqs in milliHertz).

Regards,
Mike

Quoted 3 lines
Signature · 2 lines
-- 
viresh
#15 lore raw
Quoted 15 lines · Michael Turquette

Quoting Viresh Kumar (2015-10-08 00:48:28)

Quoted 14 lines · Arnd Bergmann
Quoted 7 lines

I think it clearly makes sense to have a fixed length for each of these members:

either 32 bit is enough to represent all possible values, then there is no need to make them 'long' on 64-bit architectures, or 32 bit is not enough and then the code is broken on 32-bit architectures today and should be fixed.

I agree.

But I am not 100% sure why it was done this way to start with. Probably this is the logic behind that:
- Max clock rate supported by a u32 is ~ 4.295 GHz

The limit is actually half that when you consider clk_round_rate() returns a long, because clk_round_rate() needs to be able to return errors.

The use of long and unsigned long was done in the knowledge that it'd restrict to 2GHz the upper limit, partially because 64-bit math on 32-bit systems is inefficient and expensive, and I initially wanted people to use the thing, so it had to be lean and fast. (If I'd started out with something as complex as the CCF, it would've been laughed out as being "far too complex" and "we don't need this").

It also started out as a way to convey clock information to drivers for peripherals, which commonly don't need clocks up in the GHz range, indeed, it was rare at that time the API was designed for peripheral clocks to be much above 100MHz.

Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
#16 lore raw

PATCH 1/1 PM / OPP: fix debugfs files for 64-bit

Quoting Russell King - ARM Linux (2015-10-19 08:53:11)

Quoted 28 lines · Michael Turquette
Quoted 15 lines

Quoting Viresh Kumar (2015-10-08 00:48:28)

Quoted 14 lines · Arnd Bergmann
Quoted 7 lines

I think it clearly makes sense to have a fixed length for each of these members:

either 32 bit is enough to represent all possible values, then there is no need to make them 'long' on 64-bit architectures, or 32 bit is not enough and then the code is broken on 32-bit architectures today and should be fixed.

I agree.

But I am not 100% sure why it was done this way to start with. Probably this is the logic behind that:
- Max clock rate supported by a u32 is ~ 4.295 GHz

The limit is actually half that when you consider clk_round_rate() returns a long, because clk_round_rate() needs to be able to return errors.

The use of long and unsigned long was done in the knowledge that it'd restrict to 2GHz the upper limit, partially because 64-bit math on 32-bit systems is inefficient and expensive, and I initially wanted people to use the thing, so it had to be lean and fast. (If I'd started out with something as complex as the CCF, it would've been laughed out as being "far too complex" and "we don't need this").

Quoted 4 lines

It also started out as a way to convey clock information to drivers for peripherals, which commonly don't need clocks up in the GHz range, indeed, it was rare at that time the API was designed for peripheral clocks to be much above 100MHz.

And this is still very true today. We've had a few instances where platforms hit the 2GHz limit on a PLL feeding a divider to a CPU, but the current state of things is working for the common case.

The big question is whether to change it in anticipation of higher clock rates (somebody has to drive those THz transceivers and photonic interconnects!) or just wait until enough people start screaming.

Regards,
Mike

Quoted 4 lines
Signature · 3 lines
-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
#17 lore raw
In reply to Viresh Kumar
Quoted 8 lines · Viresh Kumar
Quoted 2 lines · Greg Kroah-Hartman

Why would you be wanting to create a "unsigned long" as an api anyway? Just force it to be u64 all the time, can't you do that?

Okay, so the variable in question (lets say frequency) is an 'unsigned long' and that's how all the APIs of clock framework expect/define it.

Quoted 7 lines

And you are probably saying that we do this:

unsigned long freq;

debugfs_create_u64((u64 *)&freq);

Right? Or are you asking to update clock APIs to be converted to u64?

Don't you even think about doing that - that's totally broken no matter what, and this is a good example of why casts are Bad.

debugfs_create_u64() will create a debugfs object that will want to access a 64-bit value, but the value pointed to is only 32-bit. The net result is that the debugfs file ends up reading or writing the neigbouring 32-bits, which may potentially be unaligned.

The variable pointed to for debugfs_create_u64() must be a 64-bit value. No casts allowed.

An alternative would be to have debugfs_create_ulong() or similar which has accessors for standard C types.

I don't think forcing subsystems wanting to use debugfs to have to use u{8,16,32,64} types for internal data is on - these are for things that we want to say "we want this to be a 8, 16, 32 or 64-bit type respectively" which is not what most subsystems need to do with internal data. This looks like a debugfs cockup to me. :)

Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
#18 lore raw
Quoted 7 lines · Russell King - ARM Linux

Don't you even think about doing that - that's totally broken no matter what, and this is a good example of why casts are Bad.

debugfs_create_u64() will create a debugfs object that will want to access a 64-bit value, but the value pointed to is only 32-bit. The net result is that the debugfs file ends up reading or writing the neigbouring 32-bits, which may potentially be unaligned.

Yeah, that's what I was also saying. Its broken.

Quoted 4 lines

The variable pointed to for debugfs_create_u64() must be a 64-bit value. No casts allowed.

An alternative would be to have debugfs_create_ulong()

And that's what I suggested.

Signature · 1 line
viresh