aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/dynamic_debug.c98
-rw-r--r--lib/kobject.c39
2 files changed, 112 insertions, 25 deletions
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 7bd6df781ce5..3094318bfea7 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -393,6 +393,40 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
393 return 0; 393 return 0;
394} 394}
395 395
396static int ddebug_exec_query(char *query_string)
397{
398 unsigned int flags = 0, mask = 0;
399 struct ddebug_query query;
400#define MAXWORDS 9
401 int nwords;
402 char *words[MAXWORDS];
403
404 nwords = ddebug_tokenize(query_string, words, MAXWORDS);
405 if (nwords <= 0)
406 return -EINVAL;
407 if (ddebug_parse_query(words, nwords-1, &query))
408 return -EINVAL;
409 if (ddebug_parse_flags(words[nwords-1], &flags, &mask))
410 return -EINVAL;
411
412 /* actually go and implement the change */
413 ddebug_change(&query, flags, mask);
414 return 0;
415}
416
417static __initdata char ddebug_setup_string[1024];
418static __init int ddebug_setup_query(char *str)
419{
420 if (strlen(str) >= 1024) {
421 pr_warning("ddebug boot param string too large\n");
422 return 0;
423 }
424 strcpy(ddebug_setup_string, str);
425 return 1;
426}
427
428__setup("ddebug_query=", ddebug_setup_query);
429
396/* 430/*
397 * File_ops->write method for <debugfs>/dynamic_debug/conrol. Gathers the 431 * File_ops->write method for <debugfs>/dynamic_debug/conrol. Gathers the
398 * command text from userspace, parses and executes it. 432 * command text from userspace, parses and executes it.
@@ -400,12 +434,8 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
400static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf, 434static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
401 size_t len, loff_t *offp) 435 size_t len, loff_t *offp)
402{ 436{
403 unsigned int flags = 0, mask = 0;
404 struct ddebug_query query;
405#define MAXWORDS 9
406 int nwords;
407 char *words[MAXWORDS];
408 char tmpbuf[256]; 437 char tmpbuf[256];
438 int ret;
409 439
410 if (len == 0) 440 if (len == 0)
411 return 0; 441 return 0;
@@ -419,16 +449,9 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
419 printk(KERN_INFO "%s: read %d bytes from userspace\n", 449 printk(KERN_INFO "%s: read %d bytes from userspace\n",
420 __func__, (int)len); 450 __func__, (int)len);
421 451
422 nwords = ddebug_tokenize(tmpbuf, words, MAXWORDS); 452 ret = ddebug_exec_query(tmpbuf);
423 if (nwords <= 0) 453 if (ret)
424 return -EINVAL; 454 return ret;
425 if (ddebug_parse_query(words, nwords-1, &query))
426 return -EINVAL;
427 if (ddebug_parse_flags(words[nwords-1], &flags, &mask))
428 return -EINVAL;
429
430 /* actually go and implement the change */
431 ddebug_change(&query, flags, mask);
432 455
433 *offp += len; 456 *offp += len;
434 return len; 457 return len;
@@ -689,13 +712,14 @@ static void ddebug_remove_all_tables(void)
689 mutex_unlock(&ddebug_lock); 712 mutex_unlock(&ddebug_lock);
690} 713}
691 714
692static int __init dynamic_debug_init(void) 715static __initdata int ddebug_init_success;
716
717static int __init dynamic_debug_init_debugfs(void)
693{ 718{
694 struct dentry *dir, *file; 719 struct dentry *dir, *file;
695 struct _ddebug *iter, *iter_start; 720
696 const char *modname = NULL; 721 if (!ddebug_init_success)
697 int ret = 0; 722 return -ENODEV;
698 int n = 0;
699 723
700 dir = debugfs_create_dir("dynamic_debug", NULL); 724 dir = debugfs_create_dir("dynamic_debug", NULL);
701 if (!dir) 725 if (!dir)
@@ -706,6 +730,16 @@ static int __init dynamic_debug_init(void)
706 debugfs_remove(dir); 730 debugfs_remove(dir);
707 return -ENOMEM; 731 return -ENOMEM;
708 } 732 }
733 return 0;
734}
735
736static int __init dynamic_debug_init(void)
737{
738 struct _ddebug *iter, *iter_start;
739 const char *modname = NULL;
740 int ret = 0;
741 int n = 0;
742
709 if (__start___verbose != __stop___verbose) { 743 if (__start___verbose != __stop___verbose) {
710 iter = __start___verbose; 744 iter = __start___verbose;
711 modname = iter->modname; 745 modname = iter->modname;
@@ -723,12 +757,26 @@ static int __init dynamic_debug_init(void)
723 } 757 }
724 ret = ddebug_add_module(iter_start, n, modname); 758 ret = ddebug_add_module(iter_start, n, modname);
725 } 759 }
760
761 /* ddebug_query boot param got passed -> set it up */
762 if (ddebug_setup_string[0] != '\0') {
763 ret = ddebug_exec_query(ddebug_setup_string);
764 if (ret)
765 pr_warning("Invalid ddebug boot param %s",
766 ddebug_setup_string);
767 else
768 pr_info("ddebug initialized with string %s",
769 ddebug_setup_string);
770 }
771
726out_free: 772out_free:
727 if (ret) { 773 if (ret)
728 ddebug_remove_all_tables(); 774 ddebug_remove_all_tables();
729 debugfs_remove(dir); 775 else
730 debugfs_remove(file); 776 ddebug_init_success = 1;
731 }
732 return 0; 777 return 0;
733} 778}
734module_init(dynamic_debug_init); 779/* Allow early initialization for boot messages via boot param */
780arch_initcall(dynamic_debug_init);
781/* Debugfs setup must be done later */
782module_init(dynamic_debug_init_debugfs);
diff --git a/lib/kobject.c b/lib/kobject.c
index f07c57252e82..82dc34c095c2 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -746,17 +746,56 @@ void kset_unregister(struct kset *k)
746 */ 746 */
747struct kobject *kset_find_obj(struct kset *kset, const char *name) 747struct kobject *kset_find_obj(struct kset *kset, const char *name)
748{ 748{
749 return kset_find_obj_hinted(kset, name, NULL);
750}
751
752/**
753 * kset_find_obj_hinted - search for object in kset given a predecessor hint.
754 * @kset: kset we're looking in.
755 * @name: object's name.
756 * @hint: hint to possible object's predecessor.
757 *
758 * Check the hint's next object and if it is a match return it directly,
759 * otherwise, fall back to the behavior of kset_find_obj(). Either way
760 * a reference for the returned object is held and the reference on the
761 * hinted object is released.
762 */
763struct kobject *kset_find_obj_hinted(struct kset *kset, const char *name,
764 struct kobject *hint)
765{
749 struct kobject *k; 766 struct kobject *k;
750 struct kobject *ret = NULL; 767 struct kobject *ret = NULL;
751 768
752 spin_lock(&kset->list_lock); 769 spin_lock(&kset->list_lock);
770
771 if (!hint)
772 goto slow_search;
773
774 /* end of list detection */
775 if (hint->entry.next == kset->list.next)
776 goto slow_search;
777
778 k = container_of(hint->entry.next, struct kobject, entry);
779 if (!kobject_name(k) || strcmp(kobject_name(k), name))
780 goto slow_search;
781
782 ret = kobject_get(k);
783 goto unlock_exit;
784
785slow_search:
753 list_for_each_entry(k, &kset->list, entry) { 786 list_for_each_entry(k, &kset->list, entry) {
754 if (kobject_name(k) && !strcmp(kobject_name(k), name)) { 787 if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
755 ret = kobject_get(k); 788 ret = kobject_get(k);
756 break; 789 break;
757 } 790 }
758 } 791 }
792
793unlock_exit:
759 spin_unlock(&kset->list_lock); 794 spin_unlock(&kset->list_lock);
795
796 if (hint)
797 kobject_put(hint);
798
760 return ret; 799 return ret;
761} 800}
762 801