Skip to content

Commit 7d8bae5

Browse files
fujitaintel-lab-lkp
authored andcommitted
sched/core: Add __might_sleep_precision()
Add __might_sleep_precision(), Rust friendly version of __might_sleep(), which takes a pointer to a string with the length instead of a null-terminated string. Rust's core::panic::Location::file(), which gives the file name of a caller, doesn't provide a null-terminated string. __might_sleep_precision() uses a precision specifier in the printk format, which specifies the length of a string; a string doesn't need to be a null-terminated. Modify __might_sleep() to call __might_sleep_precision() but the impact should be negligible. strlen() isn't called in a normal case; it's called only when printing the error (sleeping function called from invalid context). Note that Location::file() providing a null-terminated string for better C interoperability is under discussion [1]. [1]: rust-lang/libs-team#466 Co-developed-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
1 parent 606489d commit 7d8bae5

File tree

2 files changed

+36
-21
lines changed

2 files changed

+36
-21
lines changed

include/linux/kernel.h

+2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ extern int dynamic_might_resched(void);
8787
#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
8888
extern void __might_resched(const char *file, int line, unsigned int offsets);
8989
extern void __might_sleep(const char *file, int line);
90+
extern void __might_sleep_precision(const char *file, int len, int line);
9091
extern void __cant_sleep(const char *file, int line, int preempt_offset);
9192
extern void __cant_migrate(const char *file, int line);
9293

@@ -145,6 +146,7 @@ extern void __cant_migrate(const char *file, int line);
145146
static inline void __might_resched(const char *file, int line,
146147
unsigned int offsets) { }
147148
static inline void __might_sleep(const char *file, int line) { }
149+
static inline void __might_sleep_precision(const char *file, int len, int line) { }
148150
# define might_sleep() do { might_resched(); } while (0)
149151
# define cant_sleep() do { } while (0)
150152
# define cant_migrate() do { } while (0)

kernel/sched/core.c

+34-21
Original file line numberDiff line numberDiff line change
@@ -8666,24 +8666,6 @@ void __init sched_init(void)
86668666

86678667
#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
86688668

8669-
void __might_sleep(const char *file, int line)
8670-
{
8671-
unsigned int state = get_current_state();
8672-
/*
8673-
* Blocking primitives will set (and therefore destroy) current->state,
8674-
* since we will exit with TASK_RUNNING make sure we enter with it,
8675-
* otherwise we will destroy state.
8676-
*/
8677-
WARN_ONCE(state != TASK_RUNNING && current->task_state_change,
8678-
"do not call blocking ops when !TASK_RUNNING; "
8679-
"state=%x set at [<%p>] %pS\n", state,
8680-
(void *)current->task_state_change,
8681-
(void *)current->task_state_change);
8682-
8683-
__might_resched(file, line, 0);
8684-
}
8685-
EXPORT_SYMBOL(__might_sleep);
8686-
86878669
static void print_preempt_disable_ip(int preempt_offset, unsigned long ip)
86888670
{
86898671
if (!IS_ENABLED(CONFIG_DEBUG_PREEMPT))
@@ -8705,7 +8687,8 @@ static inline bool resched_offsets_ok(unsigned int offsets)
87058687
return nested == offsets;
87068688
}
87078689

8708-
void __might_resched(const char *file, int line, unsigned int offsets)
8690+
static void __might_resched_precision(const char *file, int len, int line,
8691+
unsigned int offsets)
87098692
{
87108693
/* Ratelimiting timestamp: */
87118694
static unsigned long prev_jiffy;
@@ -8728,8 +8711,10 @@ void __might_resched(const char *file, int line, unsigned int offsets)
87288711
/* Save this before calling printk(), since that will clobber it: */
87298712
preempt_disable_ip = get_preempt_disable_ip(current);
87308713

8731-
pr_err("BUG: sleeping function called from invalid context at %s:%d\n",
8732-
file, line);
8714+
if (len < 0)
8715+
len = strlen(file);
8716+
pr_err("BUG: sleeping function called from invalid context at %.*s:%d\n",
8717+
len, file, line);
87338718
pr_err("in_atomic(): %d, irqs_disabled(): %d, non_block: %d, pid: %d, name: %s\n",
87348719
in_atomic(), irqs_disabled(), current->non_block_count,
87358720
current->pid, current->comm);
@@ -8754,8 +8739,36 @@ void __might_resched(const char *file, int line, unsigned int offsets)
87548739
dump_stack();
87558740
add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
87568741
}
8742+
8743+
void __might_resched(const char *file, int line, unsigned int offsets)
8744+
{
8745+
__might_resched_precision(file, -1, line, offsets);
8746+
}
87578747
EXPORT_SYMBOL(__might_resched);
87588748

8749+
void __might_sleep_precision(const char *file, int len, int line)
8750+
{
8751+
unsigned int state = get_current_state();
8752+
/*
8753+
* Blocking primitives will set (and therefore destroy) current->state,
8754+
* since we will exit with TASK_RUNNING make sure we enter with it,
8755+
* otherwise we will destroy state.
8756+
*/
8757+
WARN_ONCE(state != TASK_RUNNING && current->task_state_change,
8758+
"do not call blocking ops when !TASK_RUNNING; "
8759+
"state=%x set at [<%p>] %pS\n", state,
8760+
(void *)current->task_state_change,
8761+
(void *)current->task_state_change);
8762+
8763+
__might_resched_precision(file, len, line, 0);
8764+
}
8765+
8766+
void __might_sleep(const char *file, int line)
8767+
{
8768+
__might_sleep_precision(file, -1, line);
8769+
}
8770+
EXPORT_SYMBOL(__might_sleep);
8771+
87598772
void __cant_sleep(const char *file, int line, int preempt_offset)
87608773
{
87618774
static unsigned long prev_jiffy;

0 commit comments

Comments
 (0)