From 3a0a58211994ddbc85ab60a102cdc8ef0c82a8fd Mon Sep 17 00:00:00 2001 From: Peter Bigot Date: Fri, 4 Oct 2019 11:28:52 -0500 Subject: [PATCH] scripts/coccinelle: updates and improvements for integer timeout values Add support for the report and patch modes so this can be invoked by coccicheck. Use PCRE options to make the kernel timeout API identifier rule more readable. Extend the pattern to new API. Use rule extends and depends clauses, and pattern disjunction, to avoid replicating metavariable content. Hint that using --include-headers may be helpful (some patterns can be found in static inline functions). Signed-off-by: Peter Bigot --- .../coccinelle/int_literal_to_timeout.cocci | 161 ++++++++++++------ 1 file changed, 109 insertions(+), 52 deletions(-) diff --git a/scripts/coccinelle/int_literal_to_timeout.cocci b/scripts/coccinelle/int_literal_to_timeout.cocci index 3c43262d086..99f0b31f85c 100644 --- a/scripts/coccinelle/int_literal_to_timeout.cocci +++ b/scripts/coccinelle/int_literal_to_timeout.cocci @@ -7,75 +7,132 @@ // integer milliseconds, when they were intended to be timeout values // produced by specific constants and macros. Convert the integer // literals to the desired equivalent. +// +// Options: --include-headers -// Handle k_timer_start delay parameters -@delay_id@ -expression T, P; -position p; +virtual patch +virtual report + +// ** Handle timeouts at the last position of kernel API arguments + +// Base rule provides the complex identifier regular expression +@r_last_timeout@ +identifier last_timeout =~ "(?x)^k_ +( timer_start +| queue_get +| futex_wait +| stack_pop +| delayed_work_submit(|_to_queue) +| work_poll_submit(|_to_queue) +| mutex_lock +| sem_take +| (msgq|mbox|pipe)_(block_)?(put|get) +| mem_(slab|pool)_alloc +| poll +| thread_deadline_set +)$"; +@@ +last_timeout(...) + +// Identify call sites where an identifier is used for the timeout +@r_last_timeout_id + extends r_last_timeout +@ identifier D; +position p; @@ -k_timer_start@p(T, D, P) +last_timeout@p(..., D) +// Select call sites where a constant literal (not identifier) is used +// for the timeout and replace the constant with the appropriate macro + +@r_last_timeout_const_patch + extends r_last_timeout + depends on patch +@ +constant C; +position p != r_last_timeout_id.p; @@ -expression T, P; -position p != delay_id.p; -@@ -k_timer_start@p(T, +last_timeout@p(..., +( - 0 + K_NO_WAIT - , P) - -@@ -expression T, P; -position p != delay_id.p; -@@ -k_timer_start@p(T, +| - -1 + K_FOREVER - , P) +| +- C ++ K_MSEC(C) +) + ) +@r_last_timeout_const_report + extends r_last_timeout + depends on report +@ +constant C; +position p != r_last_timeout_id.p; @@ -expression T, P; -constant int D; -position p != delay_id.p; +last_timeout@p(..., C) + +@script:python + depends on report +@ +fn << r_last_timeout.last_timeout; +p << r_last_timeout_const_report.p; +C << r_last_timeout_const_report.C; +@@ +msg = "WARNING: replace constant {} with timeout in {}".format(C, fn) +coccilib.report.print_report(p[0], msg); + +// ** Handle k_timer_start where the second (not last) argument is a +// ** constant literal. + +// Select call sites where an identifier is used for the duration timeout +@r_timer_duration@ +expression T; +identifier D; +expression I; +position p; +@@ +k_timer_start@p(T, D, I) + +// Select call sites where a constant literal (not identifier) is used +// for the timeout and replace the constant with the appropriate macro +@depends on patch@ +expression T; +constant C; +expression I; +position p != r_timer_duration.p; @@ k_timer_start@p(T, -- D -+ K_MSEC(D) - , P) - -// Handle timeouts at the end of the argument list -@end_id@ -identifier f =~ "^k_(timer_start|queue_get|futex_wait|stack_pop|delayed_work_submit_to_queue|mutex_lock|sem_take|(msgq|mbox|pipe)_(block_)?(put|get)|mem_(slab|pool)_alloc|poll|thread_deadline_set)$"; -position p; -identifier D; -@@ -f@p(..., D) - -@@ -identifier f =~ "^k_(timer_start|queue_get|futex_wait|stack_pop|delayed_work_submit_to_queue|mutex_lock|sem_take|(msgq|mbox|pipe)_(block_)?(put|get)|mem_(slab|pool)_alloc|poll|thread_deadline_set)$"; -position p != end_id.p; -@@ -f@p(..., +( - 0 + K_NO_WAIT - ) - -@@ -identifier f =~ "^k_(timer_start|queue_get|futex_wait|stack_pop|delayed_work_submit_to_queue|mutex_lock|sem_take|(msgq|mbox|pipe)_(block_)?(put|get)|mem_(slab|pool)_alloc|poll|thread_deadline_set)$"; -position p != end_id.p; -@@ -f@p(..., +| - -1 + K_FOREVER - ) +| +- C ++ K_MSEC(C) +) +, I) +@r_timer_duration_report + depends on report +@ +expression T; +constant C; +expression I; +position p != r_timer_duration.p; @@ -identifier f =~ "^k_(timer_start|queue_get|futex_wait|stack_pop|delayed_work_submit_to_queue|mutex_lock|sem_take|(msgq|mbox|pipe)_(block_)?(put|get)|mem_(slab|pool)_alloc|poll|thread_deadline_set)$"; -position p != end_id.p; -constant int D; +k_timer_start@p(T, C, I) + +@script:python + depends on report +@ +p << r_timer_duration_report.p; +C << r_timer_duration_report.C; @@ -f@p(..., -- D -+ K_MSEC(D) - ) +msg = "WARNING: replace constant {} with duration timeout in k_timer_start".format(C) +coccilib.report.print_report(p[0], msg);