From: Lennart Poettering Date: Tue, 26 Mar 2019 19:11:30 +0000 (+0100) Subject: tree-wide: reorder various structures to make them smaller and use fewer cache lines X-Git-Tag: v242-rc1~53 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0a6991e0bb84c4c240325899357699dc808a315b;p=thirdparty%2Fsystemd.git tree-wide: reorder various structures to make them smaller and use fewer cache lines Some "pahole" spelunking. --- diff --git a/src/core/cgroup.h b/src/core/cgroup.h index 42da777c298..51e7c96d60f 100644 --- a/src/core/cgroup.h +++ b/src/core/cgroup.h @@ -79,6 +79,10 @@ struct CGroupContext { bool tasks_accounting; bool ip_accounting; + bool delegate; + CGroupMask delegate_controllers; + CGroupMask disable_controllers; + /* For unified hierarchy */ uint64_t cpu_weight; uint64_t startup_cpu_weight; @@ -116,11 +120,6 @@ struct CGroupContext { /* Common */ uint64_t tasks_max; - - bool delegate; - CGroupMask delegate_controllers; - - CGroupMask disable_controllers; }; /* Used when querying IP accounting data */ diff --git a/src/core/dynamic-user.h b/src/core/dynamic-user.h index 112f91e63a0..0a55630ab9b 100644 --- a/src/core/dynamic-user.h +++ b/src/core/dynamic-user.h @@ -15,8 +15,8 @@ typedef struct DynamicCreds { * used. This means, if you want to allocate a group and user pair, and they might have two different names, then you * need to allocated two of these objects. DynamicCreds below makes that easy. */ struct DynamicUser { - unsigned n_ref; Manager *manager; + unsigned n_ref; /* An AF_UNIX socket pair that contains a datagram containing both the numeric ID assigned, as well as a lock * file fd locking the user ID we picked. */ diff --git a/src/core/execute.h b/src/core/execute.h index b9c0f28f99e..b612a10e2e6 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -80,9 +80,9 @@ typedef enum ExecKeyringMode { /* Contains start and exit information about an executed command. */ struct ExecStatus { - pid_t pid; dual_timestamp start_timestamp; dual_timestamp exit_timestamp; + pid_t pid; int code; /* as in siginfo_t::si_code */ int status; /* as in sigingo_t::si_status */ }; @@ -149,8 +149,21 @@ struct ExecContext { struct rlimit *rlimit[_RLIMIT_MAX]; char *working_directory, *root_directory, *root_image; - bool working_directory_missing_ok; - bool working_directory_home; + bool working_directory_missing_ok:1; + bool working_directory_home:1; + + bool oom_score_adjust_set:1; + bool nice_set:1; + bool ioprio_set:1; + bool cpu_sched_set:1; + + /* This is not exposed to the user but available internally. We need it to make sure that whenever we + * spawn /usr/bin/mount it is run in the same process group as us so that the autofs logic detects + * that it belongs to us and we don't enter a trigger loop. */ + bool same_pgrp; + + bool cpu_sched_reset_on_fork; + bool non_blocking; mode_t umask; int oom_score_adjust; @@ -159,12 +172,13 @@ struct ExecContext { int cpu_sched_policy; int cpu_sched_priority; - cpu_set_t *cpuset; unsigned cpuset_ncpus; + cpu_set_t *cpuset; ExecInput std_input; ExecOutput std_output; ExecOutput std_error; + bool stdio_as_fds; char *stdio_fdname[3]; char *stdio_file[3]; @@ -173,8 +187,6 @@ struct ExecContext { nsec_t timer_slack_nsec; - bool stdio_as_fds; - char *tty_path; bool tty_reset; @@ -183,6 +195,8 @@ struct ExecContext { bool ignore_sigpipe; + ExecKeyringMode keyring_mode; + /* Since resolving these names might involve socket * connections and we don't want to deadlock ourselves these * names are resolved on execution only and in the child @@ -196,16 +210,15 @@ struct ExecContext { char *utmp_id; ExecUtmpMode utmp_mode; - bool selinux_context_ignore; - char *selinux_context; + bool no_new_privileges; + bool selinux_context_ignore; bool apparmor_profile_ignore; - char *apparmor_profile; - bool smack_process_label_ignore; - char *smack_process_label; - ExecKeyringMode keyring_mode; + char *selinux_context; + char *apparmor_profile; + char *smack_process_label; char **read_write_paths, **read_only_paths, **inaccessible_paths; unsigned long mount_flags; @@ -219,10 +232,8 @@ struct ExecContext { int secure_bits; int syslog_priority; - char *syslog_identifier; bool syslog_level_prefix; - - int log_level_max; + char *syslog_identifier; struct iovec* log_extra_fields; size_t n_log_extra_fields; @@ -230,34 +241,29 @@ struct ExecContext { usec_t log_rate_limit_interval_usec; unsigned log_rate_limit_burst; - bool cpu_sched_reset_on_fork; - bool non_blocking; + int log_level_max; + bool private_tmp; bool private_network; bool private_devices; bool private_users; bool private_mounts; - ProtectSystem protect_system; - ProtectHome protect_home; bool protect_kernel_tunables; bool protect_kernel_modules; bool protect_control_groups; + ProtectSystem protect_system; + ProtectHome protect_home; + bool protect_hostname; bool mount_apivfs; - bool no_new_privileges; - bool dynamic_user; bool remove_ipc; - /* This is not exposed to the user but available - * internally. We need it to make sure that whenever we spawn - * /usr/bin/mount it is run in the same process group as us so - * that the autofs logic detects that it belongs to us and we - * don't enter a trigger loop. */ - bool same_pgrp; + bool memory_deny_write_execute; + bool restrict_realtime; - unsigned long personality; bool lock_personality; + unsigned long personality; unsigned long restrict_namespaces; /* The CLONE_NEWxyz flags permitted to the unit's processes */ @@ -266,22 +272,13 @@ struct ExecContext { int syscall_errno; bool syscall_whitelist:1; - Set *address_families; bool address_families_whitelist:1; - - ExecPreserveMode runtime_directory_preserve_mode; - ExecDirectory directories[_EXEC_DIRECTORY_TYPE_MAX]; - - bool memory_deny_write_execute; - bool restrict_realtime; - bool protect_hostname; - - bool oom_score_adjust_set:1; - bool nice_set:1; - bool ioprio_set:1; - bool cpu_sched_set:1; + Set *address_families; char *network_namespace_path; + + ExecDirectory directories[_EXEC_DIRECTORY_TYPE_MAX]; + ExecPreserveMode runtime_directory_preserve_mode; }; static inline bool exec_context_restrict_namespaces_set(const ExecContext *c) { diff --git a/src/core/kill.h b/src/core/kill.h index f3915be1dcf..43648b6d8a2 100644 --- a/src/core/kill.h +++ b/src/core/kill.h @@ -22,9 +22,9 @@ struct KillContext { KillMode kill_mode; int kill_signal; int final_kill_signal; + int watchdog_signal; bool send_sigkill; bool send_sighup; - int watchdog_signal; }; typedef enum KillWho { diff --git a/src/core/service.h b/src/core/service.h index 9c4340c70e3..57eefbb34dd 100644 --- a/src/core/service.h +++ b/src/core/service.h @@ -152,6 +152,7 @@ struct Service { /* Keep restart intention between UNIT_FAILED and UNIT_ACTIVATING */ bool will_auto_restart:1; bool start_timeout_defined:1; + bool exec_fd_hot:1; char *bus_name; char *bus_name_owner; /* unique name of the current owner */ @@ -183,7 +184,6 @@ struct Service { unsigned n_restarts; bool flush_n_restarts; - bool exec_fd_hot; }; extern const UnitVTable service_vtable; diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h index 831c257978b..5d6cce01685 100644 --- a/src/libsystemd/sd-bus/bus-internal.h +++ b/src/libsystemd/sd-bus/bus-internal.h @@ -64,11 +64,11 @@ struct node { struct node_callback { struct node *node; - bool is_fallback; - sd_bus_message_handler_t callback; - + bool is_fallback:1; unsigned last_iteration; + sd_bus_message_handler_t callback; + LIST_FIELDS(struct node_callback, callbacks); }; @@ -91,13 +91,13 @@ struct node_object_manager { struct node_vtable { struct node *node; + bool is_fallback:1; + unsigned last_iteration; + char *interface; - bool is_fallback; const sd_bus_vtable *vtable; sd_bus_object_find_t find; - unsigned last_iteration; - LIST_FIELDS(struct node_vtable, vtables); }; @@ -123,9 +123,6 @@ typedef enum BusSlotType { struct sd_bus_slot { unsigned n_ref; - sd_bus *bus; - void *userdata; - sd_bus_destroy_t destroy_callback; BusSlotType type:5; /* Slots can be "floating" or not. If they are not floating (the usual case) then they reference the bus object @@ -137,6 +134,11 @@ struct sd_bus_slot { bool floating:1; bool match_added:1; + + sd_bus *bus; + void *userdata; + sd_bus_destroy_t destroy_callback; + char *description; LIST_FIELDS(sd_bus_slot, slots); @@ -209,7 +211,7 @@ struct sd_bus { bool connected_signal:1; bool close_on_exit:1; - int use_memfd; + int use_memfd:2; void *rbuffer; size_t rbuffer_size; @@ -240,8 +242,8 @@ struct sd_bus { union sockaddr_union sockaddr; socklen_t sockaddr_size; - char *machine; pid_t nspid; + char *machine; sd_id128_t server_id; @@ -251,9 +253,9 @@ struct sd_bus { int last_connect_error; enum bus_auth auth; - size_t auth_rbegin; - struct iovec auth_iovec[3]; unsigned auth_index; + struct iovec auth_iovec[3]; + size_t auth_rbegin; char *auth_buffer; usec_t auth_timeout; @@ -270,8 +272,6 @@ struct sd_bus { char *exec_path; char **exec_argv; - unsigned iteration_counter; - /* We do locking around the memfd cache, since we want to * allow people to process a sd_bus_message in a different * thread then it was generated on and free it there. Since @@ -285,6 +285,8 @@ struct sd_bus { pid_t original_pid; pid_t busexec_pid; + unsigned iteration_counter; + sd_event_source *input_io_event_source; sd_event_source *output_io_event_source; sd_event_source *time_event_source; @@ -293,13 +295,14 @@ struct sd_bus { sd_event *event; int event_priority; + pid_t tid; + sd_bus_message *current_message; sd_bus_slot *current_slot; sd_bus_message_handler_t current_handler; void *current_userdata; sd_bus **default_bus_ptr; - pid_t tid; char *description; char *patch_sender;