Message ID | 20250114-kcov-v1-4-004294b931a2@quicinc.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | kcov: Introduce New Unique PC|EDGE|CMP Modes | expand |
Hi Joey, kernel test robot noticed the following build errors: [auto build test ERROR on 9b2ffa6148b1e4468d08f7e0e7e371c43cac9ffe] url: https://github.com/intel-lab-lkp/linux/commits/Jiao-Joey/kcov-introduce-new-kcov-KCOV_TRACE_UNIQ_PC-mode/20250114-133713 base: 9b2ffa6148b1e4468d08f7e0e7e371c43cac9ffe patch link: https://lore.kernel.org/r/20250114-kcov-v1-4-004294b931a2%40quicinc.com patch subject: [PATCH 4/7] kcov: introduce new kcov KCOV_TRACE_UNIQ_CMP mode config: mips-randconfig-r073-20250124 (https://download.01.org/0day-ci/archive/20250124/202501240959.61XLxBYF-lkp@intel.com/config) compiler: mips-linux-gcc (GCC) 14.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250124/202501240959.61XLxBYF-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202501240959.61XLxBYF-lkp@intel.com/ All errors (new ones prefixed by >>): kernel/kcov.c: In function 'kcov_map_add': >> kernel/kcov.c:309:60: error: 'struct kcov_entry' has no member named 'type' 309 | if (entry->ent == ent->ent && entry->type == ent->type && | ^~ kernel/kcov.c:309:73: error: 'struct kcov_entry' has no member named 'type' 309 | if (entry->ent == ent->ent && entry->type == ent->type && | ^~ >> kernel/kcov.c:310:34: error: 'struct kcov_entry' has no member named 'arg1' 310 | entry->arg1 == ent->arg1 && entry->arg2 == ent->arg2) { | ^~ kernel/kcov.c:310:47: error: 'struct kcov_entry' has no member named 'arg1' 310 | entry->arg1 == ent->arg1 && entry->arg2 == ent->arg2) { | ^~ >> kernel/kcov.c:310:62: error: 'struct kcov_entry' has no member named 'arg2' 310 | entry->arg1 == ent->arg1 && entry->arg2 == ent->arg2) { | ^~ kernel/kcov.c:310:75: error: 'struct kcov_entry' has no member named 'arg2' 310 | entry->arg1 == ent->arg1 && entry->arg2 == ent->arg2) { | ^~ kernel/kcov.c:343:48: error: 'struct kcov_entry' has no member named 'type' 343 | area[start_index] = ent->type; | ^~ kernel/kcov.c:344:52: error: 'struct kcov_entry' has no member named 'arg1' 344 | area[start_index + 1] = ent->arg1; | ^~ kernel/kcov.c:345:52: error: 'struct kcov_entry' has no member named 'arg2' 345 | area[start_index + 2] = ent->arg2; | ^~ vim +309 kernel/kcov.c 290 291 static notrace inline void kcov_map_add(struct kcov_map *map, struct kcov_entry *ent, 292 struct task_struct *t, unsigned int mode) 293 { 294 struct kcov *kcov; 295 struct kcov_entry *entry; 296 unsigned int key = hash_key(ent); 297 unsigned long pos, start_index, end_pos, max_pos, *area; 298 299 kcov = t->kcov; 300 301 if ((mode == KCOV_MODE_TRACE_UNIQ_PC || 302 mode == KCOV_MODE_TRACE_UNIQ_EDGE)) 303 hash_for_each_possible_rcu(map->buckets, entry, node, key) { 304 if (entry->ent == ent->ent) 305 return; 306 } 307 else 308 hash_for_each_possible_rcu(map->buckets, entry, node, key) { > 309 if (entry->ent == ent->ent && entry->type == ent->type && > 310 entry->arg1 == ent->arg1 && entry->arg2 == ent->arg2) { 311 return; 312 } 313 } 314 315 entry = (struct kcov_entry *)gen_pool_alloc(map->pool, 1 << MIN_POOL_ALLOC_ORDER); 316 if (unlikely(!entry)) 317 return; 318 319 barrier(); 320 memcpy(entry, ent, sizeof(*entry)); 321 hash_add_rcu(map->buckets, &entry->node, key); 322 323 if (mode == KCOV_MODE_TRACE_UNIQ_PC || mode == KCOV_MODE_TRACE_UNIQ_CMP) 324 area = t->kcov_area; 325 else 326 area = kcov->map_edge->area; 327 328 pos = READ_ONCE(area[0]) + 1; 329 if (mode == KCOV_MODE_TRACE_UNIQ_PC || mode == KCOV_MODE_TRACE_UNIQ_EDGE) { 330 if (likely(pos < t->kcov_size)) { 331 WRITE_ONCE(area[0], pos); 332 barrier(); 333 area[pos] = ent->ent; 334 } 335 } else { 336 start_index = 1 + (pos - 1) * KCOV_WORDS_PER_CMP; 337 max_pos = t->kcov_size * sizeof(unsigned long); 338 end_pos = (start_index + KCOV_WORDS_PER_CMP) * sizeof(u64); 339 if (likely(end_pos <= max_pos)) { 340 /* See comment in __sanitizer_cov_trace_pc(). */ 341 WRITE_ONCE(area[0], pos); 342 barrier(); 343 area[start_index] = ent->type; 344 area[start_index + 1] = ent->arg1; 345 area[start_index + 2] = ent->arg2; 346 area[start_index + 3] = ent->ent; 347 } 348 } 349 } 350
Hi Joey, kernel test robot noticed the following build errors: [auto build test ERROR on 9b2ffa6148b1e4468d08f7e0e7e371c43cac9ffe] url: https://github.com/intel-lab-lkp/linux/commits/Jiao-Joey/kcov-introduce-new-kcov-KCOV_TRACE_UNIQ_PC-mode/20250114-133713 base: 9b2ffa6148b1e4468d08f7e0e7e371c43cac9ffe patch link: https://lore.kernel.org/r/20250114-kcov-v1-4-004294b931a2%40quicinc.com patch subject: [PATCH 4/7] kcov: introduce new kcov KCOV_TRACE_UNIQ_CMP mode config: x86_64-randconfig-001-20250124 (https://download.01.org/0day-ci/archive/20250124/202501242043.KmrFufhL-lkp@intel.com/config) compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250124/202501242043.KmrFufhL-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202501242043.KmrFufhL-lkp@intel.com/ All errors (new ones prefixed by >>): >> kernel/kcov.c:309:41: error: no member named 'type' in 'struct kcov_entry' 309 | if (entry->ent == ent->ent && entry->type == ent->type && | ~~~~~ ^ kernel/kcov.c:309:54: error: no member named 'type' in 'struct kcov_entry' 309 | if (entry->ent == ent->ent && entry->type == ent->type && | ~~~ ^ >> kernel/kcov.c:310:15: error: no member named 'arg1' in 'struct kcov_entry' 310 | entry->arg1 == ent->arg1 && entry->arg2 == ent->arg2) { | ~~~~~ ^ kernel/kcov.c:310:28: error: no member named 'arg1' in 'struct kcov_entry' 310 | entry->arg1 == ent->arg1 && entry->arg2 == ent->arg2) { | ~~~ ^ >> kernel/kcov.c:310:43: error: no member named 'arg2' in 'struct kcov_entry' 310 | entry->arg1 == ent->arg1 && entry->arg2 == ent->arg2) { | ~~~~~ ^ kernel/kcov.c:310:56: error: no member named 'arg2' in 'struct kcov_entry' 310 | entry->arg1 == ent->arg1 && entry->arg2 == ent->arg2) { | ~~~ ^ kernel/kcov.c:343:29: error: no member named 'type' in 'struct kcov_entry' 343 | area[start_index] = ent->type; | ~~~ ^ kernel/kcov.c:344:33: error: no member named 'arg1' in 'struct kcov_entry' 344 | area[start_index + 1] = ent->arg1; | ~~~ ^ kernel/kcov.c:345:33: error: no member named 'arg2' in 'struct kcov_entry' 345 | area[start_index + 2] = ent->arg2; | ~~~ ^ 9 errors generated. vim +309 kernel/kcov.c 290 291 static notrace inline void kcov_map_add(struct kcov_map *map, struct kcov_entry *ent, 292 struct task_struct *t, unsigned int mode) 293 { 294 struct kcov *kcov; 295 struct kcov_entry *entry; 296 unsigned int key = hash_key(ent); 297 unsigned long pos, start_index, end_pos, max_pos, *area; 298 299 kcov = t->kcov; 300 301 if ((mode == KCOV_MODE_TRACE_UNIQ_PC || 302 mode == KCOV_MODE_TRACE_UNIQ_EDGE)) 303 hash_for_each_possible_rcu(map->buckets, entry, node, key) { 304 if (entry->ent == ent->ent) 305 return; 306 } 307 else 308 hash_for_each_possible_rcu(map->buckets, entry, node, key) { > 309 if (entry->ent == ent->ent && entry->type == ent->type && > 310 entry->arg1 == ent->arg1 && entry->arg2 == ent->arg2) { 311 return; 312 } 313 } 314 315 entry = (struct kcov_entry *)gen_pool_alloc(map->pool, 1 << MIN_POOL_ALLOC_ORDER); 316 if (unlikely(!entry)) 317 return; 318 319 barrier(); 320 memcpy(entry, ent, sizeof(*entry)); 321 hash_add_rcu(map->buckets, &entry->node, key); 322 323 if (mode == KCOV_MODE_TRACE_UNIQ_PC || mode == KCOV_MODE_TRACE_UNIQ_CMP) 324 area = t->kcov_area; 325 else 326 area = kcov->map_edge->area; 327 328 pos = READ_ONCE(area[0]) + 1; 329 if (mode == KCOV_MODE_TRACE_UNIQ_PC || mode == KCOV_MODE_TRACE_UNIQ_EDGE) { 330 if (likely(pos < t->kcov_size)) { 331 WRITE_ONCE(area[0], pos); 332 barrier(); 333 area[pos] = ent->ent; 334 } 335 } else { 336 start_index = 1 + (pos - 1) * KCOV_WORDS_PER_CMP; 337 max_pos = t->kcov_size * sizeof(unsigned long); 338 end_pos = (start_index + KCOV_WORDS_PER_CMP) * sizeof(u64); 339 if (likely(end_pos <= max_pos)) { 340 /* See comment in __sanitizer_cov_trace_pc(). */ 341 WRITE_ONCE(area[0], pos); 342 barrier(); 343 area[start_index] = ent->type; 344 area[start_index + 1] = ent->arg1; 345 area[start_index + 2] = ent->arg2; 346 area[start_index + 3] = ent->ent; 347 } 348 } 349 } 350
diff --git a/include/linux/kcov.h b/include/linux/kcov.h index 56b858205ba16c47fc72bda9938c98f034503c8c..a78d78164bf75368c71a958a5438fc3ee68c95ca 100644 --- a/include/linux/kcov.h +++ b/include/linux/kcov.h @@ -27,6 +27,8 @@ enum kcov_mode { KCOV_MODE_TRACE_UNIQ_PC = 16, /* Collecting uniq edge mode. */ KCOV_MODE_TRACE_UNIQ_EDGE = 32, + /* Collecting uniq cmp mode. */ + KCOV_MODE_TRACE_UNIQ_CMP = 64, }; #define KCOV_IN_CTXSW (1 << 30) diff --git a/include/uapi/linux/kcov.h b/include/uapi/linux/kcov.h index 9b2019f0ab8b8cb5426d2d6b74472fa1a7293817..08abfca273c9624dc54a2c70b12a4a9302700f26 100644 --- a/include/uapi/linux/kcov.h +++ b/include/uapi/linux/kcov.h @@ -39,6 +39,8 @@ enum { KCOV_TRACE_UNIQ_PC = 2, /* Collecting uniq edge mode. */ KCOV_TRACE_UNIQ_EDGE = 4, + /* Collecting uniq CMP mode. */ + KCOV_TRACE_UNIQ_CMP = 8, }; /* diff --git a/kernel/kcov.c b/kernel/kcov.c index c04bbec9ac3186a5145240de8ac609ad8a7ca733..af73c40114d23adedab8318e8657d24bf36ae865 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c @@ -36,6 +36,11 @@ struct kcov_entry { unsigned long ent; +#ifdef CONFIG_KCOV_ENABLE_COMPARISONS + unsigned long type; + unsigned long arg1; + unsigned long arg2; +#endif struct hlist_node node; }; @@ -44,7 +49,7 @@ struct kcov_entry { #define MIN_POOL_ALLOC_ORDER ilog2(roundup_pow_of_two(sizeof(struct kcov_entry))) /* - * kcov hashmap to store uniq pc, prealloced mem for kcov_entry + * kcov hashmap to store uniq pc|edge|cmp, prealloced mem for kcov_entry * and area shared between kernel and userspace. */ struct kcov_map { @@ -87,7 +92,7 @@ struct kcov { unsigned long prev_pc; /* Coverage buffer shared with user space. */ void *area; - /* Coverage hashmap for unique pc. */ + /* Coverage hashmap for unique pc|cmp. */ struct kcov_map *map; /* Edge hashmap for unique edge. */ struct kcov_map *map_edge; @@ -289,14 +294,23 @@ static notrace inline void kcov_map_add(struct kcov_map *map, struct kcov_entry struct kcov *kcov; struct kcov_entry *entry; unsigned int key = hash_key(ent); - unsigned long pos, *area; + unsigned long pos, start_index, end_pos, max_pos, *area; kcov = t->kcov; - hash_for_each_possible_rcu(map->buckets, entry, node, key) { - if (entry->ent == ent->ent) - return; - } + if ((mode == KCOV_MODE_TRACE_UNIQ_PC || + mode == KCOV_MODE_TRACE_UNIQ_EDGE)) + hash_for_each_possible_rcu(map->buckets, entry, node, key) { + if (entry->ent == ent->ent) + return; + } + else + hash_for_each_possible_rcu(map->buckets, entry, node, key) { + if (entry->ent == ent->ent && entry->type == ent->type && + entry->arg1 == ent->arg1 && entry->arg2 == ent->arg2) { + return; + } + } entry = (struct kcov_entry *)gen_pool_alloc(map->pool, 1 << MIN_POOL_ALLOC_ORDER); if (unlikely(!entry)) @@ -306,16 +320,31 @@ static notrace inline void kcov_map_add(struct kcov_map *map, struct kcov_entry memcpy(entry, ent, sizeof(*entry)); hash_add_rcu(map->buckets, &entry->node, key); - if (mode == KCOV_MODE_TRACE_UNIQ_PC) + if (mode == KCOV_MODE_TRACE_UNIQ_PC || mode == KCOV_MODE_TRACE_UNIQ_CMP) area = t->kcov_area; else area = kcov->map_edge->area; pos = READ_ONCE(area[0]) + 1; - if (likely(pos < t->kcov_size)) { - WRITE_ONCE(area[0], pos); - barrier(); - area[pos] = ent->ent; + if (mode == KCOV_MODE_TRACE_UNIQ_PC || mode == KCOV_MODE_TRACE_UNIQ_EDGE) { + if (likely(pos < t->kcov_size)) { + WRITE_ONCE(area[0], pos); + barrier(); + area[pos] = ent->ent; + } + } else { + start_index = 1 + (pos - 1) * KCOV_WORDS_PER_CMP; + max_pos = t->kcov_size * sizeof(unsigned long); + end_pos = (start_index + KCOV_WORDS_PER_CMP) * sizeof(u64); + if (likely(end_pos <= max_pos)) { + /* See comment in __sanitizer_cov_trace_pc(). */ + WRITE_ONCE(area[0], pos); + barrier(); + area[start_index] = ent->type; + area[start_index + 1] = ent->arg1; + area[start_index + 2] = ent->arg2; + area[start_index + 3] = ent->ent; + } } } @@ -384,33 +413,44 @@ static void notrace write_comp_data(u64 type, u64 arg1, u64 arg2, u64 ip) struct task_struct *t; u64 *area; u64 count, start_index, end_pos, max_pos; + struct kcov_entry entry = {0}; + unsigned int mode; t = current; - if (!check_kcov_mode(KCOV_MODE_TRACE_CMP, t)) + if (!check_kcov_mode(KCOV_MODE_TRACE_CMP | KCOV_MODE_TRACE_UNIQ_CMP, t)) return; + mode = t->kcov_mode; ip = canonicalize_ip(ip); - /* - * We write all comparison arguments and types as u64. - * The buffer was allocated for t->kcov_size unsigned longs. - */ - area = (u64 *)t->kcov_area; - max_pos = t->kcov_size * sizeof(unsigned long); - - count = READ_ONCE(area[0]); - - /* Every record is KCOV_WORDS_PER_CMP 64-bit words. */ - start_index = 1 + count * KCOV_WORDS_PER_CMP; - end_pos = (start_index + KCOV_WORDS_PER_CMP) * sizeof(u64); - if (likely(end_pos <= max_pos)) { - /* See comment in __sanitizer_cov_trace_pc(). */ - WRITE_ONCE(area[0], count + 1); - barrier(); - area[start_index] = type; - area[start_index + 1] = arg1; - area[start_index + 2] = arg2; - area[start_index + 3] = ip; + if (mode == KCOV_MODE_TRACE_CMP) { + /* + * We write all comparison arguments and types as u64. + * The buffer was allocated for t->kcov_size unsigned longs. + */ + area = (u64 *)t->kcov_area; + max_pos = t->kcov_size * sizeof(unsigned long); + + count = READ_ONCE(area[0]); + + /* Every record is KCOV_WORDS_PER_CMP 64-bit words. */ + start_index = 1 + count * KCOV_WORDS_PER_CMP; + end_pos = (start_index + KCOV_WORDS_PER_CMP) * sizeof(u64); + if (likely(end_pos <= max_pos)) { + /* See comment in __sanitizer_cov_trace_pc(). */ + WRITE_ONCE(area[0], count + 1); + barrier(); + area[start_index] = type; + area[start_index + 1] = arg1; + area[start_index + 2] = arg2; + area[start_index + 3] = ip; + } + } else { + entry.type = type; + entry.arg1 = arg1; + entry.arg2 = arg2; + entry.ent = ip; + kcov_map_add(t->kcov->map, &entry, t, KCOV_MODE_TRACE_UNIQ_CMP); } } @@ -730,6 +770,12 @@ static int kcov_get_mode(unsigned long arg) mode |= KCOV_MODE_TRACE_UNIQ_PC; if (arg & KCOV_TRACE_UNIQ_EDGE) mode |= KCOV_MODE_TRACE_UNIQ_EDGE; + if (arg == KCOV_TRACE_UNIQ_CMP) +#ifdef CONFIG_KCOV_ENABLE_COMPARISONS + mode = KCOV_MODE_TRACE_UNIQ_CMP; +#else + return -EOPNOTSUPP; +#endif if (!mode) return -EINVAL;
Similar to KCOV_TRACE_CMP mode, KCOV_TRACE_UNIQ_CMP stores unique CMP data into area. Signed-off-by: Jiao, Joey <quic_jiangenj@quicinc.com> --- include/linux/kcov.h | 2 + include/uapi/linux/kcov.h | 2 + kernel/kcov.c | 112 ++++++++++++++++++++++++++++++++-------------- 3 files changed, 83 insertions(+), 33 deletions(-)