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.

tracing: Move pid filtering into trace_pid.c

The trace.c file was a dumping ground for most tracing code. Start
organizing it better by moving various functions out into their own files.
Move the PID filtering functions from trace.c into its own trace_pid.c
file.

Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Link: https://patch.msgid.link/20260208032450.998330662@kernel.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

+247 -242
+1
kernel/trace/Makefile
··· 68 68 obj-$(CONFIG_TRACING) += trace_seq.o 69 69 obj-$(CONFIG_TRACING) += trace_stat.o 70 70 obj-$(CONFIG_TRACING) += trace_printk.o 71 + obj-$(CONFIG_TRACING) += trace_pid.o 71 72 obj-$(CONFIG_TRACING) += pid_list.o 72 73 obj-$(CONFIG_TRACING_MAP) += tracing_map.o 73 74 obj-$(CONFIG_PREEMPTIRQ_DELAY_TEST) += preemptirq_delay_test.o
-242
kernel/trace/trace.c
··· 637 637 return 0; 638 638 } 639 639 640 - /** 641 - * trace_find_filtered_pid - check if a pid exists in a filtered_pid list 642 - * @filtered_pids: The list of pids to check 643 - * @search_pid: The PID to find in @filtered_pids 644 - * 645 - * Returns true if @search_pid is found in @filtered_pids, and false otherwise. 646 - */ 647 - bool 648 - trace_find_filtered_pid(struct trace_pid_list *filtered_pids, pid_t search_pid) 649 - { 650 - return trace_pid_list_is_set(filtered_pids, search_pid); 651 - } 652 - 653 - /** 654 - * trace_ignore_this_task - should a task be ignored for tracing 655 - * @filtered_pids: The list of pids to check 656 - * @filtered_no_pids: The list of pids not to be traced 657 - * @task: The task that should be ignored if not filtered 658 - * 659 - * Checks if @task should be traced or not from @filtered_pids. 660 - * Returns true if @task should *NOT* be traced. 661 - * Returns false if @task should be traced. 662 - */ 663 - bool 664 - trace_ignore_this_task(struct trace_pid_list *filtered_pids, 665 - struct trace_pid_list *filtered_no_pids, 666 - struct task_struct *task) 667 - { 668 - /* 669 - * If filtered_no_pids is not empty, and the task's pid is listed 670 - * in filtered_no_pids, then return true. 671 - * Otherwise, if filtered_pids is empty, that means we can 672 - * trace all tasks. If it has content, then only trace pids 673 - * within filtered_pids. 674 - */ 675 - 676 - return (filtered_pids && 677 - !trace_find_filtered_pid(filtered_pids, task->pid)) || 678 - (filtered_no_pids && 679 - trace_find_filtered_pid(filtered_no_pids, task->pid)); 680 - } 681 - 682 - /** 683 - * trace_filter_add_remove_task - Add or remove a task from a pid_list 684 - * @pid_list: The list to modify 685 - * @self: The current task for fork or NULL for exit 686 - * @task: The task to add or remove 687 - * 688 - * If adding a task, if @self is defined, the task is only added if @self 689 - * is also included in @pid_list. This happens on fork and tasks should 690 - * only be added when the parent is listed. If @self is NULL, then the 691 - * @task pid will be removed from the list, which would happen on exit 692 - * of a task. 693 - */ 694 - void trace_filter_add_remove_task(struct trace_pid_list *pid_list, 695 - struct task_struct *self, 696 - struct task_struct *task) 697 - { 698 - if (!pid_list) 699 - return; 700 - 701 - /* For forks, we only add if the forking task is listed */ 702 - if (self) { 703 - if (!trace_find_filtered_pid(pid_list, self->pid)) 704 - return; 705 - } 706 - 707 - /* "self" is set for forks, and NULL for exits */ 708 - if (self) 709 - trace_pid_list_set(pid_list, task->pid); 710 - else 711 - trace_pid_list_clear(pid_list, task->pid); 712 - } 713 - 714 - /** 715 - * trace_pid_next - Used for seq_file to get to the next pid of a pid_list 716 - * @pid_list: The pid list to show 717 - * @v: The last pid that was shown (+1 the actual pid to let zero be displayed) 718 - * @pos: The position of the file 719 - * 720 - * This is used by the seq_file "next" operation to iterate the pids 721 - * listed in a trace_pid_list structure. 722 - * 723 - * Returns the pid+1 as we want to display pid of zero, but NULL would 724 - * stop the iteration. 725 - */ 726 - void *trace_pid_next(struct trace_pid_list *pid_list, void *v, loff_t *pos) 727 - { 728 - long pid = (unsigned long)v; 729 - unsigned int next; 730 - 731 - (*pos)++; 732 - 733 - /* pid already is +1 of the actual previous bit */ 734 - if (trace_pid_list_next(pid_list, pid, &next) < 0) 735 - return NULL; 736 - 737 - pid = next; 738 - 739 - /* Return pid + 1 to allow zero to be represented */ 740 - return (void *)(pid + 1); 741 - } 742 - 743 - /** 744 - * trace_pid_start - Used for seq_file to start reading pid lists 745 - * @pid_list: The pid list to show 746 - * @pos: The position of the file 747 - * 748 - * This is used by seq_file "start" operation to start the iteration 749 - * of listing pids. 750 - * 751 - * Returns the pid+1 as we want to display pid of zero, but NULL would 752 - * stop the iteration. 753 - */ 754 - void *trace_pid_start(struct trace_pid_list *pid_list, loff_t *pos) 755 - { 756 - unsigned long pid; 757 - unsigned int first; 758 - loff_t l = 0; 759 - 760 - if (trace_pid_list_first(pid_list, &first) < 0) 761 - return NULL; 762 - 763 - pid = first; 764 - 765 - /* Return pid + 1 so that zero can be the exit value */ 766 - for (pid++; pid && l < *pos; 767 - pid = (unsigned long)trace_pid_next(pid_list, (void *)pid, &l)) 768 - ; 769 - return (void *)pid; 770 - } 771 - 772 - /** 773 - * trace_pid_show - show the current pid in seq_file processing 774 - * @m: The seq_file structure to write into 775 - * @v: A void pointer of the pid (+1) value to display 776 - * 777 - * Can be directly used by seq_file operations to display the current 778 - * pid value. 779 - */ 780 - int trace_pid_show(struct seq_file *m, void *v) 781 - { 782 - unsigned long pid = (unsigned long)v - 1; 783 - 784 - seq_printf(m, "%lu\n", pid); 785 - return 0; 786 - } 787 - 788 - /* 128 should be much more than enough */ 789 - #define PID_BUF_SIZE 127 790 - 791 - int trace_pid_write(struct trace_pid_list *filtered_pids, 792 - struct trace_pid_list **new_pid_list, 793 - const char __user *ubuf, size_t cnt) 794 - { 795 - struct trace_pid_list *pid_list; 796 - struct trace_parser parser; 797 - unsigned long val; 798 - int nr_pids = 0; 799 - ssize_t read = 0; 800 - ssize_t ret; 801 - loff_t pos; 802 - pid_t pid; 803 - 804 - if (trace_parser_get_init(&parser, PID_BUF_SIZE + 1)) 805 - return -ENOMEM; 806 - 807 - /* 808 - * Always recreate a new array. The write is an all or nothing 809 - * operation. Always create a new array when adding new pids by 810 - * the user. If the operation fails, then the current list is 811 - * not modified. 812 - */ 813 - pid_list = trace_pid_list_alloc(); 814 - if (!pid_list) { 815 - trace_parser_put(&parser); 816 - return -ENOMEM; 817 - } 818 - 819 - if (filtered_pids) { 820 - /* copy the current bits to the new max */ 821 - ret = trace_pid_list_first(filtered_pids, &pid); 822 - while (!ret) { 823 - ret = trace_pid_list_set(pid_list, pid); 824 - if (ret < 0) 825 - goto out; 826 - 827 - ret = trace_pid_list_next(filtered_pids, pid + 1, &pid); 828 - nr_pids++; 829 - } 830 - } 831 - 832 - ret = 0; 833 - while (cnt > 0) { 834 - 835 - pos = 0; 836 - 837 - ret = trace_get_user(&parser, ubuf, cnt, &pos); 838 - if (ret < 0) 839 - break; 840 - 841 - read += ret; 842 - ubuf += ret; 843 - cnt -= ret; 844 - 845 - if (!trace_parser_loaded(&parser)) 846 - break; 847 - 848 - ret = -EINVAL; 849 - if (kstrtoul(parser.buffer, 0, &val)) 850 - break; 851 - 852 - pid = (pid_t)val; 853 - 854 - if (trace_pid_list_set(pid_list, pid) < 0) { 855 - ret = -1; 856 - break; 857 - } 858 - nr_pids++; 859 - 860 - trace_parser_clear(&parser); 861 - ret = 0; 862 - } 863 - out: 864 - trace_parser_put(&parser); 865 - 866 - if (ret < 0) { 867 - trace_pid_list_free(pid_list); 868 - return ret; 869 - } 870 - 871 - if (!nr_pids) { 872 - /* Cleared the list of pids */ 873 - trace_pid_list_free(pid_list); 874 - pid_list = NULL; 875 - } 876 - 877 - *new_pid_list = pid_list; 878 - 879 - return read; 880 - } 881 - 882 640 static u64 buffer_ftrace_now(struct array_buffer *buf, int cpu) 883 641 { 884 642 u64 ts;
+246
kernel/trace/trace_pid.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include "trace.h" 4 + 5 + /** 6 + * trace_find_filtered_pid - check if a pid exists in a filtered_pid list 7 + * @filtered_pids: The list of pids to check 8 + * @search_pid: The PID to find in @filtered_pids 9 + * 10 + * Returns true if @search_pid is found in @filtered_pids, and false otherwise. 11 + */ 12 + bool 13 + trace_find_filtered_pid(struct trace_pid_list *filtered_pids, pid_t search_pid) 14 + { 15 + return trace_pid_list_is_set(filtered_pids, search_pid); 16 + } 17 + 18 + /** 19 + * trace_ignore_this_task - should a task be ignored for tracing 20 + * @filtered_pids: The list of pids to check 21 + * @filtered_no_pids: The list of pids not to be traced 22 + * @task: The task that should be ignored if not filtered 23 + * 24 + * Checks if @task should be traced or not from @filtered_pids. 25 + * Returns true if @task should *NOT* be traced. 26 + * Returns false if @task should be traced. 27 + */ 28 + bool 29 + trace_ignore_this_task(struct trace_pid_list *filtered_pids, 30 + struct trace_pid_list *filtered_no_pids, 31 + struct task_struct *task) 32 + { 33 + /* 34 + * If filtered_no_pids is not empty, and the task's pid is listed 35 + * in filtered_no_pids, then return true. 36 + * Otherwise, if filtered_pids is empty, that means we can 37 + * trace all tasks. If it has content, then only trace pids 38 + * within filtered_pids. 39 + */ 40 + 41 + return (filtered_pids && 42 + !trace_find_filtered_pid(filtered_pids, task->pid)) || 43 + (filtered_no_pids && 44 + trace_find_filtered_pid(filtered_no_pids, task->pid)); 45 + } 46 + 47 + /** 48 + * trace_filter_add_remove_task - Add or remove a task from a pid_list 49 + * @pid_list: The list to modify 50 + * @self: The current task for fork or NULL for exit 51 + * @task: The task to add or remove 52 + * 53 + * If adding a task, if @self is defined, the task is only added if @self 54 + * is also included in @pid_list. This happens on fork and tasks should 55 + * only be added when the parent is listed. If @self is NULL, then the 56 + * @task pid will be removed from the list, which would happen on exit 57 + * of a task. 58 + */ 59 + void trace_filter_add_remove_task(struct trace_pid_list *pid_list, 60 + struct task_struct *self, 61 + struct task_struct *task) 62 + { 63 + if (!pid_list) 64 + return; 65 + 66 + /* For forks, we only add if the forking task is listed */ 67 + if (self) { 68 + if (!trace_find_filtered_pid(pid_list, self->pid)) 69 + return; 70 + } 71 + 72 + /* "self" is set for forks, and NULL for exits */ 73 + if (self) 74 + trace_pid_list_set(pid_list, task->pid); 75 + else 76 + trace_pid_list_clear(pid_list, task->pid); 77 + } 78 + 79 + /** 80 + * trace_pid_next - Used for seq_file to get to the next pid of a pid_list 81 + * @pid_list: The pid list to show 82 + * @v: The last pid that was shown (+1 the actual pid to let zero be displayed) 83 + * @pos: The position of the file 84 + * 85 + * This is used by the seq_file "next" operation to iterate the pids 86 + * listed in a trace_pid_list structure. 87 + * 88 + * Returns the pid+1 as we want to display pid of zero, but NULL would 89 + * stop the iteration. 90 + */ 91 + void *trace_pid_next(struct trace_pid_list *pid_list, void *v, loff_t *pos) 92 + { 93 + long pid = (unsigned long)v; 94 + unsigned int next; 95 + 96 + (*pos)++; 97 + 98 + /* pid already is +1 of the actual previous bit */ 99 + if (trace_pid_list_next(pid_list, pid, &next) < 0) 100 + return NULL; 101 + 102 + pid = next; 103 + 104 + /* Return pid + 1 to allow zero to be represented */ 105 + return (void *)(pid + 1); 106 + } 107 + 108 + /** 109 + * trace_pid_start - Used for seq_file to start reading pid lists 110 + * @pid_list: The pid list to show 111 + * @pos: The position of the file 112 + * 113 + * This is used by seq_file "start" operation to start the iteration 114 + * of listing pids. 115 + * 116 + * Returns the pid+1 as we want to display pid of zero, but NULL would 117 + * stop the iteration. 118 + */ 119 + void *trace_pid_start(struct trace_pid_list *pid_list, loff_t *pos) 120 + { 121 + unsigned long pid; 122 + unsigned int first; 123 + loff_t l = 0; 124 + 125 + if (trace_pid_list_first(pid_list, &first) < 0) 126 + return NULL; 127 + 128 + pid = first; 129 + 130 + /* Return pid + 1 so that zero can be the exit value */ 131 + for (pid++; pid && l < *pos; 132 + pid = (unsigned long)trace_pid_next(pid_list, (void *)pid, &l)) 133 + ; 134 + return (void *)pid; 135 + } 136 + 137 + /** 138 + * trace_pid_show - show the current pid in seq_file processing 139 + * @m: The seq_file structure to write into 140 + * @v: A void pointer of the pid (+1) value to display 141 + * 142 + * Can be directly used by seq_file operations to display the current 143 + * pid value. 144 + */ 145 + int trace_pid_show(struct seq_file *m, void *v) 146 + { 147 + unsigned long pid = (unsigned long)v - 1; 148 + 149 + seq_printf(m, "%lu\n", pid); 150 + return 0; 151 + } 152 + 153 + /* 128 should be much more than enough */ 154 + #define PID_BUF_SIZE 127 155 + 156 + int trace_pid_write(struct trace_pid_list *filtered_pids, 157 + struct trace_pid_list **new_pid_list, 158 + const char __user *ubuf, size_t cnt) 159 + { 160 + struct trace_pid_list *pid_list; 161 + struct trace_parser parser; 162 + unsigned long val; 163 + int nr_pids = 0; 164 + ssize_t read = 0; 165 + ssize_t ret; 166 + loff_t pos; 167 + pid_t pid; 168 + 169 + if (trace_parser_get_init(&parser, PID_BUF_SIZE + 1)) 170 + return -ENOMEM; 171 + 172 + /* 173 + * Always recreate a new array. The write is an all or nothing 174 + * operation. Always create a new array when adding new pids by 175 + * the user. If the operation fails, then the current list is 176 + * not modified. 177 + */ 178 + pid_list = trace_pid_list_alloc(); 179 + if (!pid_list) { 180 + trace_parser_put(&parser); 181 + return -ENOMEM; 182 + } 183 + 184 + if (filtered_pids) { 185 + /* copy the current bits to the new max */ 186 + ret = trace_pid_list_first(filtered_pids, &pid); 187 + while (!ret) { 188 + ret = trace_pid_list_set(pid_list, pid); 189 + if (ret < 0) 190 + goto out; 191 + 192 + ret = trace_pid_list_next(filtered_pids, pid + 1, &pid); 193 + nr_pids++; 194 + } 195 + } 196 + 197 + ret = 0; 198 + while (cnt > 0) { 199 + 200 + pos = 0; 201 + 202 + ret = trace_get_user(&parser, ubuf, cnt, &pos); 203 + if (ret < 0) 204 + break; 205 + 206 + read += ret; 207 + ubuf += ret; 208 + cnt -= ret; 209 + 210 + if (!trace_parser_loaded(&parser)) 211 + break; 212 + 213 + ret = -EINVAL; 214 + if (kstrtoul(parser.buffer, 0, &val)) 215 + break; 216 + 217 + pid = (pid_t)val; 218 + 219 + if (trace_pid_list_set(pid_list, pid) < 0) { 220 + ret = -1; 221 + break; 222 + } 223 + nr_pids++; 224 + 225 + trace_parser_clear(&parser); 226 + ret = 0; 227 + } 228 + out: 229 + trace_parser_put(&parser); 230 + 231 + if (ret < 0) { 232 + trace_pid_list_free(pid_list); 233 + return ret; 234 + } 235 + 236 + if (!nr_pids) { 237 + /* Cleared the list of pids */ 238 + trace_pid_list_free(pid_list); 239 + pid_list = NULL; 240 + } 241 + 242 + *new_pid_list = pid_list; 243 + 244 + return read; 245 + } 246 +