thunderbolt-power: Use bolt force power API if available#684
Conversation
|
7a1c878 to
e8d7fd1
Compare
|
|
||
| if (g_unix_fd_list_get_length (fds) != 1) { | ||
| g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, | ||
| "invalid number of file descriptors retunred: %d", |
| g_debug ("Setting force power to %d using bolt", enable); | ||
| if (enable) | ||
| return fu_plugin_thunderbolt_power_bolt_force_power (plugin, error); | ||
| if (data->bolt_fd > 0) |
There was a problem hiding this comment.
I assume we can be sure we'll never get 0 fd from dbus. But don't you need to zero it here so it'll be zero if enable fails next time?
There was a problem hiding this comment.
Also zero is a valid file descriptor. Typically -1 is used to represent invalid one.
There was a problem hiding this comment.
Thanks, adjusted the usage in the code.
| g_unix_fd_list_get_length (fds)); | ||
| return FALSE; | ||
| } | ||
| data->bolt_fd = g_unix_fd_list_get (fds, 0, NULL); |
There was a problem hiding this comment.
I'm confused why we need to use fd's like a handle -- why isn't bolt just using "NameOwnerChanged" to detect clients using ForcePower falling off the bus? The normal way clients do this kind of thing is with two methods, e.g. ForcePower() and UnForcePower() using a uint32_t "token" that allows a client to refcount. Falling off the bus is the same as UnForcePower()-ing for all tokens from that sender.
There was a problem hiding this comment.
Now I am a bit confused :) I personally think that using an fd as "token" that can be easily released via close is more elegant than having an extra dbus method plus another uint token. On the bolt side the implementation also quite straight forward, create a named pipe with a GIOChannel as the even watch (and that is all for book-keeping). One cool thing about the named pipe is that we can recover from boltd crashes and restarts (--replace) because we just re-open all the named pipes that were not closed (and that works really well in my tests).
But maybe I am missing something, do you see any big disadvantage?
| -1, | ||
| NULL, | ||
| NULL); | ||
| data->bolt_supported = (val != NULL); |
There was a problem hiding this comment.
Currently that call will return successfully with an empty array even if boltd did not detect support for force power, i.e. the wmi sysfs device is missing. I could change it to return an error (NOT_SUPPORTED or something) in that case, but I wonder if I should not change the "PowerState" enum property to include a unsupported value. Any opinions?
There was a problem hiding this comment.
If the wmi sysfs is missing this plugin will fail to load at coldplug (it still looks for this file itself for fallback currently).
It's entirely possible however that the kernel unloads the module at runtime so I would prefer to keep the test as to whether the bolt daemon has this functionality. If the module comes and goes the calls will succeed or fail when tried.
There was a problem hiding this comment.
I was wondering if it should be a different plugin entirely...
There was a problem hiding this comment.
Hmm, keeping them together in the same fwupd plugin is actually ideal in my mind. The whole reason for this bolt feature is so that only one userspace is accessing the kernel method to avoid software stomping on each other. If bolt is there, it should be used. If not, use the kernel directly. Eventually when new enough bolt is everywhere that we care about, I would actually prefer to drop the direct kernel support from fwupd.
If bolt goes into it's own plugin (say bolt-thunderbolt-power and this plugin renames to kernel-thunderbolt-power) the model for when to use the kernel-thunderbolt-power plugin becomes more complicated. There isn't really a device registered signal to look for, so how will fwupd know which to prefer?
There was a problem hiding this comment.
I was thinking about this some more this morning, and I think you're right - we need some assurance from bolt that it can actually force power. Returning an unsupported from PowerState property is sufficient as long as a fresh GDbusProxy is used every time it's checked.
There was a problem hiding this comment.
@superm1 I will go and implement that now then. I also think that GDBusProxy should keep track of property updates, but in any case a manual call to the org.freedesktop.DBus.Properties.Get method should always work, i.e. something like:
g_dbus_proxy_call (proxy,
"org.freedesktop.DBus.Properties.Get",
g_variant_new ("(ss)", BOLT_DBUS_INTERFACE, "PowerState"),
[...]
There was a problem hiding this comment.
Rather than the client need to know to look for magic PowerState property enums (ie !=unsupported), maybe a third method ForcePowerSupported would be better? Then that can instantly check whether the kernel module is loaded and give a boolean answer.
Up to you, i'll adjust the PR for whichever you decide.
There was a problem hiding this comment.
I thought about this some more and decided to extract the whole force power related properties/methods into its own interface: org.freedesktop.bolt1.Power. Both methods (ForcePower, ListGuards), the property (PowerState as State) and additionally a new boolean Supported property are exposed there (and the methods removed from the bolt1.Manager interface). I think for this PR changing BOLT_DBUS_INTERFACE to org.freedesktop.bolt1.Power should suffice; the new Supported boolean, that can be used to check if force-powering is supported or not, should come in handy.
I am also add support for monitoring changes to the intel-wmi-thunderbolt module so that the Supported property is updated accordingly. For this I am using the bind and unbind uevents (see here) — I hope that is a good way to do that.
One more thing: it seems to be totally possible to unload the module, even with force_power is set to 1 and boltd will not yet do the right thing in that case. This needs a few more changes.
|
@gicmo Once you add an unsupported enum, I think we also need a way to be notified if force power changes to/from supported (eg kernel module unload/load) that we can subscribe to. |
ae1192c to
1638839
Compare
|
@superm1 I was thinking that subscribing to |
|
Yeah that should work. |
| G_CALLBACK (udev_uevent_cb), plugin); | ||
| /* initially set to true, will wait for a device_register to reset */ | ||
| data->needs_forcepower = TRUE; | ||
| /* will reset when neeeded */ |
There was a problem hiding this comment.
Typo 'neeeded' -> 'needed'
This is new support for bolt supported by https://gitlab.freedesktop.org/bolt/bolt/merge_requests/101
1638839 to
d4ed8e3
Compare
|
@gicmo thanks. I've adjusted for your changes and use the |
|
LGTM now, if that matters. |
|
OK thanks. @gicmo merged it in bolt, so I'll merge it here too then. |
This is new support for bolt supported by
https://gitlab.freedesktop.org/bolt/bolt/merge_requests/101