New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
th/dbus_cache_properties #82
Conversation
cdbfd6e
to
759c8de
Compare
@balrog-kun, some changes to IWD code here. Does it look OK? |
if ( !ac | ||
|| !NM_IS_ACTIVE_CONNECTION (ac) | ||
|| c_list_is_empty (&ac->active_connections_lst)) | ||
return NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't these be assertions? If nm_dbus_manager_lookup_object() returns a non-NULL pointer and it's not an active connection I think there is a programming error somewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, I am in favor of assertions, but in this case, I think it's too much. Note already before, the code allowed for the possibility that the path may not exist. The possibility of a non-existing path, means the caller apparently has no control about the path he looks up, so asserting against it is wrong. Maybe in this case, for active_connection_get_by_path()
you are right. But for example nm_wifi_ap_lookup_for_device()
does something similar, and that is called with a path provided by the user (untrusted).
if ( !device | ||
|| !NM_IS_DEVICE (device) | ||
|| c_list_is_empty (&device->devices_lst)) | ||
return NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same as above, I think NM_IS_DEVICE (device) and c_list_is_empty (&device->devices_lst) should be assertions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See how nm_checkpoint_manager_create()
looks paths up from untrusted source.
@@ -174,6 +174,7 @@ struct _NMDevicePrivate; | |||
struct _NMDevice { | |||
NMDBusObject parent; | |||
struct _NMDevicePrivate *_priv; | |||
CList devices_lst; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
core: track devices in manager via embedded C-List
Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extended commit message. Ok?
GVariant is immutable and can nicely be shared and cached. Cache the property variants. This makes getting the properties faster, at the expense of using some extra memory. Tested with https://tratt.net/laurie/src/multitime/ $ multitime -n 200 -s 0 bash -c 'echo -n .; exec busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects &>/dev/null' # Mean Std.Dev. Min Median Max # real(before) 0.013+/-0.0000 0.001 0.012 0.013 0.019 # real(after) 0.013+/-0.0000 0.002 0.011 0.012 0.034 $ multitime -n 100 -s 0 bash -c 'for i in {1..5}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects &>/dev/null & done; wait; echo -n .' # Mean Std.Dev. Min Median Max # real(before) 0.040+/-0.0000 0.002 0.037 0.040 0.049 # real(after) 0.037+/-0.0000 0.002 0.034 0.036 0.045 $ multitime -n 30 -s 0 bash -c 'for i in {1..100}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects &>/dev/null & done; wait; echo -n .' # Mean Std.Dev. Min Median Max # real(before) 0.704+/-0.0000 0.016 0.687 0.701 0.766 # real(after) 0.639+/-0.0000 0.013 0.622 0.637 0.687 $ multitime -n 200 -s 0 bash -c 'echo -n .; exec nmcli &>/dev/null' # Mean Std.Dev. Min Median Max # real(before) 0.092+/-0.0000 0.005 0.081 0.092 0.119 # real(after) 0.092+/-0.0000 0.005 0.080 0.091 0.123 $ multitime -n 100 -s 0 bash -c 'for i in {1..5}; do nmcli &>/dev/null & done; wait; echo -n .' # Mean Std.Dev. Min Median Max # real(before) 0.436+/-0.0000 0.043 0.375 0.424 0.600 # real(after) 0.413+/-0.0000 0.022 0.380 0.410 0.558 $ multitime -n 20 -s 0 bash -c 'for i in {1..100}; do nmcli &>/dev/null & done; wait; echo -n .' # Mean Std.Dev. Min Median Max # real(before) 8.796+/-0.1070 0.291 8.073 8.818 9.247 # real(after) 8.736+/-0.0893 0.243 8.017 8.780 9.101 The time savings are small, but that is because caching mostly speeds up the GetManagedObjects calls, and that is only a small part of the entire nmcli call from client side.
Instead of using a GSList for tracking the devices, use a CList. I think a CList is in most cases the more suitable data structure then GSList: - you can find out in O(1) whether the object is linked. That is nice, for example to assert in NMDevice's destructor that the object was unlinked, and we will use that later in nm_manager_get_device_by_path(). - you can unlink the element in O(1) and you can unlink the element without having access to the link's head - Contrary to GSList, this does not require an extra slice allocation for the link node. It quite possibliy consumes slightly less memory because the CList structure is embedded in a struct that we already allocate. Even if slice allocation would be perfect to only consume 2*sizeof(gpointer) for the link note, it would at most be as-good as CList. Quite possibly, there is an overhead though. - CList possibly has better memory locality, because the link structure and the data are close to each other. Something which could be seen as disavantage, is that with CList one device can only be tracked in one NMManager instance at a time. But that is fine. There exists only one NMManager instance for now, and even if we would ever introduce multiple managers, we probably would not associate one NMDevice instance with multiple managers. The advantages are arguably not huge, but CList is IMHO clearly the more suited data structure. No need to stick to a suboptimal data structure for the job. Refactor it.
…_addr() For comparing MAC addresses, they anyway have to be normalized to binary. Convert it once outside the loop and pass the binary form to nm_utils_hwaddr_matches(). Otherwise, we need to re-convert it every time.
We already track an index of exported objects in NMDBusManager. Actually, that index was unused previously. We either could drop it, or use it. Let's use it.
- no longer track APs in a hash table with their exported path as key. The exported path is already tracked by NMDBusManager's lookup index, so we can reuse that for fast lookup by path. Otherwise, track the APs in a CList per device. - as we now track APs in a CList, their order is well defined. We no longer need to sort APs and obsoletes nm_wifi_aps_get_sorted() and simplifies nm_wifi_aps_find_first_compatible().
The variable serves a similar purpose, but is called "dns", "conf", and "dns_config". Choose one name: "dns_config".
- consistently set options, searches, domains fields to %NULL, if there are no values. - in nm_global_dns_config_update_checksum(), ensure that we uniquely hash values. E.g. a config with "searches[a], options=[b]" should hash differently from "searches=[ab], options=[]". - in nm_global_dns_config_to_dbus(), reuse the sorted domain list. We already have it, and it guarantees a consistent ordering of fields. - in global_dns_domain_from_dbus(), fix memleaks if D-Bus strdict contains duplicate entries.
cddc4f7
to
e49a329
Compare
LGTM now |
Thanks. Merged |
Cache property GVariants for D-Bus and make more use of
CList
to track devices in manager andNMWifiAP