Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'core-debugobjects-2024-01-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull debugobject update from Ingo Molnar:

- Make tracking object use more robust: it's not safe to access a
tracking object after releasing the hashbucket lock. Create a
persistent copy for debug printouts instead.

* tag 'core-debugobjects-2024-01-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
debugobjects: Stop accessing objects after releasing hash bucket lock

+80 -124
+80 -124
lib/debugobjects.c
··· 620 620 static void 621 621 __debug_object_init(void *addr, const struct debug_obj_descr *descr, int onstack) 622 622 { 623 - enum debug_obj_state state; 623 + struct debug_obj *obj, o; 624 624 struct debug_bucket *db; 625 - struct debug_obj *obj; 626 625 unsigned long flags; 627 626 628 627 debug_objects_fill_pool(); ··· 642 643 case ODEBUG_STATE_INIT: 643 644 case ODEBUG_STATE_INACTIVE: 644 645 obj->state = ODEBUG_STATE_INIT; 645 - break; 646 - 647 - case ODEBUG_STATE_ACTIVE: 648 - state = obj->state; 649 646 raw_spin_unlock_irqrestore(&db->lock, flags); 650 - debug_print_object(obj, "init"); 651 - debug_object_fixup(descr->fixup_init, addr, state); 652 - return; 653 - 654 - case ODEBUG_STATE_DESTROYED: 655 - raw_spin_unlock_irqrestore(&db->lock, flags); 656 - debug_print_object(obj, "init"); 657 647 return; 658 648 default: 659 649 break; 660 650 } 661 651 652 + o = *obj; 662 653 raw_spin_unlock_irqrestore(&db->lock, flags); 654 + debug_print_object(&o, "init"); 655 + 656 + if (o.state == ODEBUG_STATE_ACTIVE) 657 + debug_object_fixup(descr->fixup_init, addr, o.state); 663 658 } 664 659 665 660 /** ··· 694 701 int debug_object_activate(void *addr, const struct debug_obj_descr *descr) 695 702 { 696 703 struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr }; 697 - enum debug_obj_state state; 698 704 struct debug_bucket *db; 699 705 struct debug_obj *obj; 700 706 unsigned long flags; 701 - int ret; 702 707 703 708 if (!debug_objects_enabled) 704 709 return 0; ··· 708 717 raw_spin_lock_irqsave(&db->lock, flags); 709 718 710 719 obj = lookup_object_or_alloc(addr, db, descr, false, true); 711 - if (likely(!IS_ERR_OR_NULL(obj))) { 712 - bool print_object = false; 713 - 720 + if (unlikely(!obj)) { 721 + raw_spin_unlock_irqrestore(&db->lock, flags); 722 + debug_objects_oom(); 723 + return 0; 724 + } else if (likely(!IS_ERR(obj))) { 714 725 switch (obj->state) { 726 + case ODEBUG_STATE_ACTIVE: 727 + case ODEBUG_STATE_DESTROYED: 728 + o = *obj; 729 + break; 715 730 case ODEBUG_STATE_INIT: 716 731 case ODEBUG_STATE_INACTIVE: 717 732 obj->state = ODEBUG_STATE_ACTIVE; 718 - ret = 0; 719 - break; 720 - 721 - case ODEBUG_STATE_ACTIVE: 722 - state = obj->state; 723 - raw_spin_unlock_irqrestore(&db->lock, flags); 724 - debug_print_object(obj, "activate"); 725 - ret = debug_object_fixup(descr->fixup_activate, addr, state); 726 - return ret ? 0 : -EINVAL; 727 - 728 - case ODEBUG_STATE_DESTROYED: 729 - print_object = true; 730 - ret = -EINVAL; 731 - break; 733 + fallthrough; 732 734 default: 733 - ret = 0; 734 - break; 735 + raw_spin_unlock_irqrestore(&db->lock, flags); 736 + return 0; 735 737 } 736 - raw_spin_unlock_irqrestore(&db->lock, flags); 737 - if (print_object) 738 - debug_print_object(obj, "activate"); 739 - return ret; 740 738 } 741 739 742 740 raw_spin_unlock_irqrestore(&db->lock, flags); 743 - 744 - /* If NULL the allocation has hit OOM */ 745 - if (!obj) { 746 - debug_objects_oom(); 747 - return 0; 748 - } 749 - 750 - /* Object is neither static nor tracked. It's not initialized */ 751 741 debug_print_object(&o, "activate"); 752 - ret = debug_object_fixup(descr->fixup_activate, addr, ODEBUG_STATE_NOTAVAILABLE); 753 - return ret ? 0 : -EINVAL; 742 + 743 + switch (o.state) { 744 + case ODEBUG_STATE_ACTIVE: 745 + case ODEBUG_STATE_NOTAVAILABLE: 746 + if (debug_object_fixup(descr->fixup_activate, addr, o.state)) 747 + return 0; 748 + fallthrough; 749 + default: 750 + return -EINVAL; 751 + } 754 752 } 755 753 EXPORT_SYMBOL_GPL(debug_object_activate); 756 754 ··· 750 770 */ 751 771 void debug_object_deactivate(void *addr, const struct debug_obj_descr *descr) 752 772 { 773 + struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr }; 753 774 struct debug_bucket *db; 754 775 struct debug_obj *obj; 755 776 unsigned long flags; 756 - bool print_object = false; 757 777 758 778 if (!debug_objects_enabled) 759 779 return; ··· 765 785 obj = lookup_object(addr, db); 766 786 if (obj) { 767 787 switch (obj->state) { 788 + case ODEBUG_STATE_DESTROYED: 789 + break; 768 790 case ODEBUG_STATE_INIT: 769 791 case ODEBUG_STATE_INACTIVE: 770 792 case ODEBUG_STATE_ACTIVE: 771 - if (!obj->astate) 772 - obj->state = ODEBUG_STATE_INACTIVE; 773 - else 774 - print_object = true; 775 - break; 776 - 777 - case ODEBUG_STATE_DESTROYED: 778 - print_object = true; 779 - break; 793 + if (obj->astate) 794 + break; 795 + obj->state = ODEBUG_STATE_INACTIVE; 796 + fallthrough; 780 797 default: 781 - break; 798 + raw_spin_unlock_irqrestore(&db->lock, flags); 799 + return; 782 800 } 801 + o = *obj; 783 802 } 784 803 785 804 raw_spin_unlock_irqrestore(&db->lock, flags); 786 - if (!obj) { 787 - struct debug_obj o = { .object = addr, 788 - .state = ODEBUG_STATE_NOTAVAILABLE, 789 - .descr = descr }; 790 - 791 - debug_print_object(&o, "deactivate"); 792 - } else if (print_object) { 793 - debug_print_object(obj, "deactivate"); 794 - } 805 + debug_print_object(&o, "deactivate"); 795 806 } 796 807 EXPORT_SYMBOL_GPL(debug_object_deactivate); 797 808 ··· 793 822 */ 794 823 void debug_object_destroy(void *addr, const struct debug_obj_descr *descr) 795 824 { 796 - enum debug_obj_state state; 825 + struct debug_obj *obj, o; 797 826 struct debug_bucket *db; 798 - struct debug_obj *obj; 799 827 unsigned long flags; 800 - bool print_object = false; 801 828 802 829 if (!debug_objects_enabled) 803 830 return; ··· 805 836 raw_spin_lock_irqsave(&db->lock, flags); 806 837 807 838 obj = lookup_object(addr, db); 808 - if (!obj) 809 - goto out_unlock; 839 + if (!obj) { 840 + raw_spin_unlock_irqrestore(&db->lock, flags); 841 + return; 842 + } 810 843 811 844 switch (obj->state) { 845 + case ODEBUG_STATE_ACTIVE: 846 + case ODEBUG_STATE_DESTROYED: 847 + break; 812 848 case ODEBUG_STATE_NONE: 813 849 case ODEBUG_STATE_INIT: 814 850 case ODEBUG_STATE_INACTIVE: 815 851 obj->state = ODEBUG_STATE_DESTROYED; 816 - break; 817 - case ODEBUG_STATE_ACTIVE: 818 - state = obj->state; 819 - raw_spin_unlock_irqrestore(&db->lock, flags); 820 - debug_print_object(obj, "destroy"); 821 - debug_object_fixup(descr->fixup_destroy, addr, state); 822 - return; 823 - 824 - case ODEBUG_STATE_DESTROYED: 825 - print_object = true; 826 - break; 852 + fallthrough; 827 853 default: 828 - break; 854 + raw_spin_unlock_irqrestore(&db->lock, flags); 855 + return; 829 856 } 830 - out_unlock: 857 + 858 + o = *obj; 831 859 raw_spin_unlock_irqrestore(&db->lock, flags); 832 - if (print_object) 833 - debug_print_object(obj, "destroy"); 860 + debug_print_object(&o, "destroy"); 861 + 862 + if (o.state == ODEBUG_STATE_ACTIVE) 863 + debug_object_fixup(descr->fixup_destroy, addr, o.state); 834 864 } 835 865 EXPORT_SYMBOL_GPL(debug_object_destroy); 836 866 ··· 840 872 */ 841 873 void debug_object_free(void *addr, const struct debug_obj_descr *descr) 842 874 { 843 - enum debug_obj_state state; 875 + struct debug_obj *obj, o; 844 876 struct debug_bucket *db; 845 - struct debug_obj *obj; 846 877 unsigned long flags; 847 878 848 879 if (!debug_objects_enabled) ··· 852 885 raw_spin_lock_irqsave(&db->lock, flags); 853 886 854 887 obj = lookup_object(addr, db); 855 - if (!obj) 856 - goto out_unlock; 888 + if (!obj) { 889 + raw_spin_unlock_irqrestore(&db->lock, flags); 890 + return; 891 + } 857 892 858 893 switch (obj->state) { 859 894 case ODEBUG_STATE_ACTIVE: 860 - state = obj->state; 861 - raw_spin_unlock_irqrestore(&db->lock, flags); 862 - debug_print_object(obj, "free"); 863 - debug_object_fixup(descr->fixup_free, addr, state); 864 - return; 895 + break; 865 896 default: 866 897 hlist_del(&obj->node); 867 898 raw_spin_unlock_irqrestore(&db->lock, flags); 868 899 free_object(obj); 869 900 return; 870 901 } 871 - out_unlock: 902 + 903 + o = *obj; 872 904 raw_spin_unlock_irqrestore(&db->lock, flags); 905 + debug_print_object(&o, "free"); 906 + 907 + debug_object_fixup(descr->fixup_free, addr, o.state); 873 908 } 874 909 EXPORT_SYMBOL_GPL(debug_object_free); 875 910 ··· 923 954 debug_object_active_state(void *addr, const struct debug_obj_descr *descr, 924 955 unsigned int expect, unsigned int next) 925 956 { 957 + struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr }; 926 958 struct debug_bucket *db; 927 959 struct debug_obj *obj; 928 960 unsigned long flags; 929 - bool print_object = false; 930 961 931 962 if (!debug_objects_enabled) 932 963 return; ··· 939 970 if (obj) { 940 971 switch (obj->state) { 941 972 case ODEBUG_STATE_ACTIVE: 942 - if (obj->astate == expect) 943 - obj->astate = next; 944 - else 945 - print_object = true; 946 - break; 947 - 973 + if (obj->astate != expect) 974 + break; 975 + obj->astate = next; 976 + raw_spin_unlock_irqrestore(&db->lock, flags); 977 + return; 948 978 default: 949 - print_object = true; 950 979 break; 951 980 } 981 + o = *obj; 952 982 } 953 983 954 984 raw_spin_unlock_irqrestore(&db->lock, flags); 955 - if (!obj) { 956 - struct debug_obj o = { .object = addr, 957 - .state = ODEBUG_STATE_NOTAVAILABLE, 958 - .descr = descr }; 959 - 960 - debug_print_object(&o, "active_state"); 961 - } else if (print_object) { 962 - debug_print_object(obj, "active_state"); 963 - } 985 + debug_print_object(&o, "active_state"); 964 986 } 965 987 EXPORT_SYMBOL_GPL(debug_object_active_state); 966 988 ··· 959 999 static void __debug_check_no_obj_freed(const void *address, unsigned long size) 960 1000 { 961 1001 unsigned long flags, oaddr, saddr, eaddr, paddr, chunks; 962 - const struct debug_obj_descr *descr; 963 - enum debug_obj_state state; 1002 + int cnt, objs_checked = 0; 1003 + struct debug_obj *obj, o; 964 1004 struct debug_bucket *db; 965 1005 struct hlist_node *tmp; 966 - struct debug_obj *obj; 967 - int cnt, objs_checked = 0; 968 1006 969 1007 saddr = (unsigned long) address; 970 1008 eaddr = saddr + size; ··· 984 1026 985 1027 switch (obj->state) { 986 1028 case ODEBUG_STATE_ACTIVE: 987 - descr = obj->descr; 988 - state = obj->state; 1029 + o = *obj; 989 1030 raw_spin_unlock_irqrestore(&db->lock, flags); 990 - debug_print_object(obj, "free"); 991 - debug_object_fixup(descr->fixup_free, 992 - (void *) oaddr, state); 1031 + debug_print_object(&o, "free"); 1032 + debug_object_fixup(o.descr->fixup_free, (void *)oaddr, o.state); 993 1033 goto repeat; 994 1034 default: 995 1035 hlist_del(&obj->node);