diff options
author | hselasky <hselasky@FreeBSD.org> | 2015-12-28 18:20:05 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2015-12-28 18:20:05 +0000 |
commit | 0fc96d39d362dff30bc5839e1f2fe66c83fef8cd (patch) | |
tree | 5d0ad69c7b91286aae1f8d623530a4609ef0c85b /sys/compat/linuxkpi/common/src/linux_compat.c | |
parent | bd647f05b431df82cb8b33b8890e68a7e46c1c33 (diff) | |
download | FreeBSD-src-0fc96d39d362dff30bc5839e1f2fe66c83fef8cd.zip FreeBSD-src-0fc96d39d362dff30bc5839e1f2fe66c83fef8cd.tar.gz |
Reduce memory consumption when allocating kobject strings in the
LinuxKPI. Compute string length before allocating memory instead of
using fixed size allocations. Make kobject_set_name_vargs() global
instead of inline to save some bytes when compiling.
MFC after: 1 week
Sponsored by: Mellanox Technologies
Diffstat (limited to 'sys/compat/linuxkpi/common/src/linux_compat.c')
-rw-r--r-- | sys/compat/linuxkpi/common/src/linux_compat.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c index cc096b0..91ec693 100644 --- a/sys/compat/linuxkpi/common/src/linux_compat.c +++ b/sys/compat/linuxkpi/common/src/linux_compat.c @@ -94,7 +94,50 @@ panic_cmp(struct rb_node *one, struct rb_node *two) } RB_GENERATE(linux_root, rb_node, __entry, panic_cmp); - + +int +kobject_set_name_vargs(struct kobject *kobj, const char *fmt, va_list args) +{ + va_list tmp_va; + int len; + char *old; + char *name; + char dummy; + + old = kobj->name; + + if (old && fmt == NULL) + return (0); + + /* compute length of string */ + va_copy(tmp_va, args); + len = vsnprintf(&dummy, 0, fmt, tmp_va); + va_end(tmp_va); + + /* account for zero termination */ + len++; + + /* check for error */ + if (len < 1) + return (-EINVAL); + + /* allocate memory for string */ + name = kzalloc(len, GFP_KERNEL); + if (name == NULL) + return (-ENOMEM); + vsnprintf(name, len, fmt, args); + kobj->name = name; + + /* free old string */ + kfree(old); + + /* filter new string */ + for (; *name != '\0'; name++) + if (*name == '/') + *name = '!'; + return (0); +} + int kobject_set_name(struct kobject *kobj, const char *fmt, ...) { |