rcu.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Julia Lawall <julia.lawall@lip6.fr>
To: Valentin Schneider <valentin.schneider@arm.com>
Cc: Markus Elfring <Markus.Elfring@web.de>,
	Alexey Dobriyan <adobriyan@gmail.com>,
	dm-devel@redhat.com, linux-block@vger.kernel.org,
	rcu@vger.kernel.org, linux-kernel@vger.kernel.org,
	Andrea Arcangeli <aarcange@redhat.com>,
	Ingo Molnar <mingo@redhat.com>, Jens Axboe <axboe@kernel.dk>,
	Peter Zijlstra <peterz@infradead.org>,
	Julia Lawall <julia.lawall@lip6.fr>
Subject: Re: sched: make struct task_struct::state 32-bit
Date: Mon, 23 Sep 2019 12:34:06 +0200 (CEST)	[thread overview]
Message-ID: <alpine.DEB.2.21.1909231228200.2272@hadrien> (raw)
In-Reply-To: <32d65b15-1855-e7eb-e9c4-81560fab62ea@arm.com>



On Mon, 23 Sep 2019, Valentin Schneider wrote:

> On 05/09/2019 17:52, Valentin Schneider wrote:
> > I actually got rid of the task_struct* parameter and now just match
> > against task_struct.p accesses in the function body, which has the
> > added bonus of not caring about the order of the parameters.
> >
> > Still not there yet but making progress in the background, hope it's
> > passable entertainment to see me struggle my way there :)
> >
>
> Bit of hiatus on my end there. I did play around some more with Coccinelle
> on the way to/from Plumbers. The main problems I'm facing ATM is "current"
> not being recognized as a task_struct* expression, and the need to
> "recursively" match task_struct.state modifiers, i.e. catch both functions
> for something like:
>
> foo(long state)
> {
> 	__foo(state);
> }
>
> __foo(long state)
> {
> 	current->state = state;
> }
>
>
> Here's where I'm at:
> ---
> virtual patch
> virtual report
>
> // Match variables that represent task states
> // They can be read from / written to task_struct.state, or be compared
> // to TASK_* values
> @state_access@
> struct task_struct *p;
> // FIXME: current not recognized as task_struct*, fixhack with regexp
> identifier current =~ "^current$";

Please don't do this.  Just use the word current.  It doesn't have to be a
metavariable.  You will though get a warning about it.  To eliminate the
warning, you can say symbol current;

> identifier task_state =~ "^TASK_";

Are there a lot of options?  You can also enumerate them in {}, ie

identifier task_state = {TASK_BLAH, TASK_BLAHBLAH};

> identifier state_var;
> position pos;
> @@
>
> (
>   p->state & state_var@pos
> |
>   current->state & state_var@pos
> |
>   p->state | state_var@pos
> |
>   current->state | state_var@pos
> |
>   p->state < state_var@pos
> |
>   current->state < state_var@pos
> |
>   p->state > state_var@pos
> |
>   current->state > state_var@pos
> |
>   state_var@pos = p->state
> |
>   state_var@pos = current->state
> |
>   p->state == state_var@pos
> |
>   current->state == state_var@pos
> |
>   p->state != state_var@pos
> |
>   current->state != state_var@pos
> |
> // FIXME: match functions that do something with state_var underneath?
> // How to do recursive rules?

You want to look at the definitions of called functions?  Coccinelle
doesn't really support that, but there are hackish ways to add that.  How
many function calls would you expect have to be unrolled?

>   set_current_state(state_var@pos)
> |
>   set_special_state(state_var@pos)
> |
>   signal_pending_state(state_var@pos, p)
> |
>   signal_pending_state(state_var@pos, current)
> |
>   state_var@pos & task_state
> |
>   state_var@pos | task_state
> )
>
> // Fixup local variables
> @depends on patch && state_access@
> identifier state_var = state_access.state_var;
> @@
> (
> - long
> + int
> |
> - unsigned long
> + unsigned int
> )
> state_var;
>
> // Fixup function parameters
> @depends on patch && state_access@
> identifier fn;
> identifier state_var = state_access.state_var;
> @@
>
> fn(...,
> - long state_var
> + int state_var
> ,...)
> {
> 	...
> }
>
> // FIXME: find a way to squash that with the above?

I think that you can make a disjunction on a function parameter

fn(...,
(
- T1 x1
+ T2 x2
|
- T3 x3
+ T4 x4
)
, ...) { ... }

julia

> // Fixup function parameters
> @depends on patch && state_access@
> identifier fn;
> identifier state_var = state_access.state_var;
> @@
>
> fn(...,
> - unsigned long
> + unsigned int
> state_var
> ,...)
> {
> 	...
> }
> ---
>
> This gives me the following diff on kernel/:
>
> ---
> diff -u -p a/locking/mutex.c b/locking/mutex.c
> --- a/locking/mutex.c
> +++ b/locking/mutex.c
> @@ -923,7 +923,7 @@ __ww_mutex_add_waiter(struct mutex_waite
>   * Lock a mutex (possibly interruptible), slowpath:
>   */
>  static __always_inline int __sched
> -__mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
> +__mutex_lock_common(struct mutex *lock, int state, unsigned int subclass,
>  		    struct lockdep_map *nest_lock, unsigned long ip,
>  		    struct ww_acquire_ctx *ww_ctx, const bool use_ww_ctx)
>  {
> @@ -1097,14 +1097,14 @@ err_early_kill:
>  }
>
>  static int __sched
> -__mutex_lock(struct mutex *lock, long state, unsigned int subclass,
> +__mutex_lock(struct mutex *lock, int state, unsigned int subclass,
>  	     struct lockdep_map *nest_lock, unsigned long ip)
>  {
>  	return __mutex_lock_common(lock, state, subclass, nest_lock, ip, NULL, false);
>  }
>
>  static int __sched
> -__ww_mutex_lock(struct mutex *lock, long state, unsigned int subclass,
> +__ww_mutex_lock(struct mutex *lock, int state, unsigned int subclass,
>  		struct lockdep_map *nest_lock, unsigned long ip,
>  		struct ww_acquire_ctx *ww_ctx)
>  {
> diff -u -p a/locking/semaphore.c b/locking/semaphore.c
> --- a/locking/semaphore.c
> +++ b/locking/semaphore.c
> @@ -201,7 +201,7 @@ struct semaphore_waiter {
>   * constant, and thus optimised away by the compiler.  Likewise the
>   * 'timeout' parameter for the cases without timeouts.
>   */
> -static inline int __sched __down_common(struct semaphore *sem, long state,
> +static inline int __sched __down_common(struct semaphore *sem, int state,
>  								long timeout)
>  {
>  	struct semaphore_waiter waiter;
> diff -u -p a/freezer.c b/freezer.c
> --- a/freezer.c
> +++ b/freezer.c
> @@ -64,7 +64,7 @@ bool __refrigerator(bool check_kthr_stop
>  	/* Hmm, should we be allowed to suspend when there are realtime
>  	   processes around? */
>  	bool was_frozen = false;
> -	long save = current->state;
> +	int save = current->state;
>
>  	pr_debug("%s entered refrigerator\n", current->comm);
>
> diff -u -p a/sched/core.c b/sched/core.c
> --- a/sched/core.c
> +++ b/sched/core.c
> @@ -1888,7 +1888,7 @@ out:
>   * smp_call_function() if an IPI is sent by the same process we are
>   * waiting to become inactive.
>   */
> -unsigned long wait_task_inactive(struct task_struct *p, long match_state)
> +unsigned long wait_task_inactive(struct task_struct *p, int match_state)
>  {
>  	int running, queued;
>  	struct rq_flags rf;
> @@ -3185,7 +3185,7 @@ static struct rq *finish_task_switch(str
>  {
>  	struct rq *rq = this_rq();
>  	struct mm_struct *mm = rq->prev_mm;
> -	long prev_state;
> +	int prev_state;
>
>  	/*
>  	 * The previous task will have left us with a preempt_count of 2
> @@ -5964,7 +5964,7 @@ void sched_show_task(struct task_struct
>  EXPORT_SYMBOL_GPL(sched_show_task);
>
>  static inline bool
> -state_filter_match(unsigned long state_filter, struct task_struct *p)
> +state_filter_match(unsigned int state_filter, struct task_struct *p)
>  {
>  	/* no filter, everything matches */
>  	if (!state_filter)
> @@ -5985,7 +5985,7 @@ state_filter_match(unsigned long state_f
>  }
>
>
> -void show_state_filter(unsigned long state_filter)
> +void show_state_filter(unsigned int state_filter)
>  {
>  	struct task_struct *g, *p;
>
> ---
>

  reply	other threads:[~2019-09-23 10:34 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-02 21:05 [PATCH] sched: make struct task_struct::state 32-bit Alexey Dobriyan
2019-09-02 23:02 ` Valentin Schneider
2019-09-03 16:23   ` Alexey Dobriyan
2019-09-03 16:31     ` Valentin Schneider
2019-09-03  6:51 ` [dm-devel] " Christoph Hellwig
2019-09-03  7:13   ` Peter Zijlstra
2019-09-03 17:29 ` Valentin Schneider
2019-09-03 18:19   ` Alexey Dobriyan
2019-09-03 21:51     ` Valentin Schneider
2019-09-04 12:07       ` Valentin Schneider
2019-09-04 17:48         ` Valentin Schneider
2019-09-05 15:51         ` Markus Elfring
2019-09-05 16:52           ` Valentin Schneider
2019-09-23 10:26             ` Valentin Schneider
2019-09-23 10:34               ` Julia Lawall [this message]
2019-09-23 11:26                 ` Valentin Schneider
2019-09-23 11:43                   ` Julia Lawall
2019-09-23 13:23                     ` Valentin Schneider
2019-09-24  8:28                   ` Markus Elfring
2019-09-24  8:07               ` Markus Elfring
2019-09-04  9:43     ` [PATCH] " David Laight
2019-09-04 10:25       ` Valentin Schneider

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.DEB.2.21.1909231228200.2272@hadrien \
    --to=julia.lawall@lip6.fr \
    --cc=Markus.Elfring@web.de \
    --cc=aarcange@redhat.com \
    --cc=adobriyan@gmail.com \
    --cc=axboe@kernel.dk \
    --cc=dm-devel@redhat.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rcu@vger.kernel.org \
    --cc=valentin.schneider@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).