* Elliot Berman <quic_eberman@xxxxxxxxxxx> [2023-01-20 14:46:20]: > +static struct gunyah_vm_function_driver *__find_function(const char name[GUNYAH_FUNCTION_NAME_SIZE]) > + __must_hold(functions_lock) > +{ > + struct gunyah_vm_function_driver *iter, *drv = NULL; > + > + list_for_each_entry(iter, &functions, list) { > + if (!strncmp(iter->name, name, GUNYAH_FUNCTION_NAME_SIZE)) { > + drv = iter; > + break; > + } > + } Not sure how much of a hot path this is going to sit in. I can imagine VM boot to be in fast path for some cases (VMs spawned on usecase boundaries - I think some VMs like in Amazon firecracker boot in fraction of a second). This indirection could cost that a bit (linear search + strcmp for the right function). IMHO a direct interface (ex: ADD_IOEVENTFD) will be more efficient. > +void gunyah_vm_function_unregister(struct gunyah_vm_function_driver *drv) > +{ > + struct gunyah_vm_function *f, *iter; > + > + mutex_lock(&functions_lock); > + list_for_each_entry_safe(f, iter, &drv->instances, drv_list) > + gh_vm_remove_function(f); > + list_del(&drv->list); > + mutex_unlock(&functions_lock); This seems to allow essential functions to be unregistered while there are still active users. For example, it would allow ioeventfd or irqfd module to be unloaded while there are VMs depending on it. I think it would be better if we allow module unload (aka function_unregister) only after dependent VMs are stopped. > +static long gh_vm_rm_function(struct gunyah_vm *ghvm, struct gh_vm_function *fn) > +{ > + long r = 0; > + struct gunyah_vm_function *f, *iter; > + > + r = mutex_lock_interruptible(&functions_lock); > + if (r) > + return r; > + > + list_for_each_entry_safe(f, iter, &ghvm->functions, vm_list) { > + if (!memcmp(&f->fn, fn, sizeof(*fn))) > + gh_vm_remove_function(f); > + } > + I think we should return some error (for ioctl atleast) if given function was not found. > +struct gh_vm_function { > + char name[GUNYAH_FUNCTION_NAME_SIZE]; > + union { > + char data[GUNYAH_FUNCTION_MAX_ARG_SIZE]; > + }; Can you find a way to optimize this memory/time usage? For example, in case of ioevents we strictly need 28 bytes, but end up consuming 1kB. Also we end up comparing 1024 bytes during REMOVE_FUNCTION when strictly 28 bytes or fewer bytes comparison was required in case of ioeventfd.