linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] misc/sgi-xp: Replace in_interrupt() usage
@ 2020-11-19  8:13 Sebastian Andrzej Siewior
  2020-11-19  8:44 ` Greg Kroah-Hartman
  0 siblings, 1 reply; 4+ messages in thread
From: Sebastian Andrzej Siewior @ 2020-11-19  8:13 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Sebastian Andrzej Siewior, Greg Kroah-Hartman,
	Cliff Whickman, Arnd Bergmann, Robin Holt, Steve Wahl,
	Dimitri Sivanich, Russ Anderson

From: Thomas Gleixner <tglx@linutronix.de>

The usage of in_interrupt() in xpc_partition_disengaged() is clearly
intended to avoid canceling the timeout timer when the function is invoked
from the timer callback.

While in_interrupt() is deprecated and ill defined as it does not provide
what the name suggests it catches the intended case.

Add an argument to xpc_partition_disengaged() which is true if called
from timer and otherwise false.
Use del_timer_sync() instead of del_singleshot_timer_sync() which is the
same thing.

Note: This does not prevent reentrancy into the function as the function
has no concurrency control and timer callback and regular task context
callers can happen concurrently on different CPUs or the timer can
interrupt the task context before it is able to cancel it.

While the only driver which is providing the arch_xpc_ops callbacks
(xpc_uv) seems not to have a reentrancy problem and the only negative
effect would be a double dev_info() entry in dmesg, the whole mechanism is
conceptually broken.

But that's not subject of this cleanup endeavour and left as an exercise to
the folks who might have interest to make that code fully correct.

[bigeasy: Add the argument, use del_timer_sync().]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Cliff Whickman <cpw@sgi.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Robin Holt <robinmholt@gmail.com>
Cc: Steve Wahl <steve.wahl@hpe.com>
Cc: Dimitri Sivanich <dimitri.sivanich@hpe.com>
Cc: Russ Anderson <russ.anderson@hpe.com>
---
 drivers/misc/sgi-xp/xpc.h           | 2 +-
 drivers/misc/sgi-xp/xpc_main.c      | 8 ++++----
 drivers/misc/sgi-xp/xpc_partition.c | 9 ++++-----
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
index 71db60edff655..bbcf10ca3ab7f 100644
--- a/drivers/misc/sgi-xp/xpc.h
+++ b/drivers/misc/sgi-xp/xpc.h
@@ -633,7 +633,7 @@ extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
 extern int xpc_setup_rsvd_page(void);
 extern void xpc_teardown_rsvd_page(void);
 extern int xpc_identify_activate_IRQ_sender(void);
-extern int xpc_partition_disengaged(struct xpc_partition *);
+extern int xpc_partition_disengaged(struct xpc_partition *, bool from_timer);
 extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
 extern void xpc_mark_partition_inactive(struct xpc_partition *);
 extern void xpc_discovery(void);
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index e5244fc1dab30..c85f2434fb091 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -179,7 +179,7 @@ xpc_timeout_partition_disengage(struct timer_list *t)
 
 	DBUG_ON(time_is_after_jiffies(part->disengage_timeout));
 
-	(void)xpc_partition_disengaged(part);
+	xpc_partition_disengaged(part, true);
 
 	DBUG_ON(part->disengage_timeout != 0);
 	DBUG_ON(xpc_arch_ops.partition_engaged(XPC_PARTID(part)));
@@ -341,7 +341,7 @@ xpc_channel_mgr(struct xpc_partition *part)
 {
 	while (part->act_state != XPC_P_AS_DEACTIVATING ||
 	       atomic_read(&part->nchannels_active) > 0 ||
-	       !xpc_partition_disengaged(part)) {
+	       !xpc_partition_disengaged(part, false)) {
 
 		xpc_process_sent_chctl_flags(part);
 
@@ -364,7 +364,7 @@ xpc_channel_mgr(struct xpc_partition *part)
 				 part->chctl.all_flags != 0 ||
 				 (part->act_state == XPC_P_AS_DEACTIVATING &&
 				 atomic_read(&part->nchannels_active) == 0 &&
-				 xpc_partition_disengaged(part))));
+				 xpc_partition_disengaged(part, false))));
 		atomic_set(&part->channel_mgr_requests, 1);
 	}
 }
@@ -983,7 +983,7 @@ xpc_do_exit(enum xp_retval reason)
 		for (partid = 0; partid < xp_max_npartitions; partid++) {
 			part = &xpc_partitions[partid];
 
-			if (xpc_partition_disengaged(part) &&
+			if (xpc_partition_disengaged(part, false) &&
 			    part->act_state == XPC_P_AS_INACTIVE) {
 				continue;
 			}
diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c
index 57df06820bae2..30fa9998c5629 100644
--- a/drivers/misc/sgi-xp/xpc_partition.c
+++ b/drivers/misc/sgi-xp/xpc_partition.c
@@ -262,8 +262,7 @@ xpc_get_remote_rp(int nasid, unsigned long *discovered_nasids,
  * from us. Though we requested the remote partition to deactivate with regard
  * to us, we really only need to wait for the other side to disengage from us.
  */
-int
-xpc_partition_disengaged(struct xpc_partition *part)
+int xpc_partition_disengaged(struct xpc_partition *part, bool from_timer)
 {
 	short partid = XPC_PARTID(part);
 	int disengaged;
@@ -289,9 +288,9 @@ xpc_partition_disengaged(struct xpc_partition *part)
 		}
 		part->disengage_timeout = 0;
 
-		/* cancel the timer function, provided it's not us */
-		if (!in_interrupt())
-			del_singleshot_timer_sync(&part->disengage_timer);
+		/* Cancel the timer function if not called from it */
+		if (!from_timer)
+			del_timer_sync(&part->disengage_timer);
 
 		DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING &&
 			part->act_state != XPC_P_AS_INACTIVE);
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] misc/sgi-xp: Replace in_interrupt() usage
  2020-11-19  8:13 [PATCH] misc/sgi-xp: Replace in_interrupt() usage Sebastian Andrzej Siewior
@ 2020-11-19  8:44 ` Greg Kroah-Hartman
  2020-11-19 10:31   ` [PATCH v2] " Sebastian Andrzej Siewior
  0 siblings, 1 reply; 4+ messages in thread
From: Greg Kroah-Hartman @ 2020-11-19  8:44 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, Thomas Gleixner, Cliff Whickman, Arnd Bergmann,
	Robin Holt, Steve Wahl, Dimitri Sivanich, Russ Anderson

On Thu, Nov 19, 2020 at 09:13:54AM +0100, Sebastian Andrzej Siewior wrote:
> From: Thomas Gleixner <tglx@linutronix.de>
> 
> The usage of in_interrupt() in xpc_partition_disengaged() is clearly
> intended to avoid canceling the timeout timer when the function is invoked
> from the timer callback.
> 
> While in_interrupt() is deprecated and ill defined as it does not provide
> what the name suggests it catches the intended case.
> 
> Add an argument to xpc_partition_disengaged() which is true if called
> from timer and otherwise false.
> Use del_timer_sync() instead of del_singleshot_timer_sync() which is the
> same thing.
> 
> Note: This does not prevent reentrancy into the function as the function
> has no concurrency control and timer callback and regular task context
> callers can happen concurrently on different CPUs or the timer can
> interrupt the task context before it is able to cancel it.
> 
> While the only driver which is providing the arch_xpc_ops callbacks
> (xpc_uv) seems not to have a reentrancy problem and the only negative
> effect would be a double dev_info() entry in dmesg, the whole mechanism is
> conceptually broken.
> 
> But that's not subject of this cleanup endeavour and left as an exercise to
> the folks who might have interest to make that code fully correct.
> 
> [bigeasy: Add the argument, use del_timer_sync().]
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Cliff Whickman <cpw@sgi.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Robin Holt <robinmholt@gmail.com>
> Cc: Steve Wahl <steve.wahl@hpe.com>
> Cc: Dimitri Sivanich <dimitri.sivanich@hpe.com>
> Cc: Russ Anderson <russ.anderson@hpe.com>
> ---
>  drivers/misc/sgi-xp/xpc.h           | 2 +-
>  drivers/misc/sgi-xp/xpc_main.c      | 8 ++++----
>  drivers/misc/sgi-xp/xpc_partition.c | 9 ++++-----
>  3 files changed, 9 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
> index 71db60edff655..bbcf10ca3ab7f 100644
> --- a/drivers/misc/sgi-xp/xpc.h
> +++ b/drivers/misc/sgi-xp/xpc.h
> @@ -633,7 +633,7 @@ extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
>  extern int xpc_setup_rsvd_page(void);
>  extern void xpc_teardown_rsvd_page(void);
>  extern int xpc_identify_activate_IRQ_sender(void);
> -extern int xpc_partition_disengaged(struct xpc_partition *);
> +extern int xpc_partition_disengaged(struct xpc_partition *, bool from_timer);

These types of "flags" for functions are horrible as they do not
describe what is happening when you read the places the function is
called.

Instead, make it part of the function name itself:
	xpc_partition_disengaged_from_timer()
and then handle it that way, by using a shared static function with the
flag.

Otherwise this type of change just does not age well at all.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2] misc/sgi-xp: Replace in_interrupt() usage
  2020-11-19  8:44 ` Greg Kroah-Hartman
@ 2020-11-19 10:31   ` Sebastian Andrzej Siewior
  2020-11-19 16:11     ` Steve Wahl
  0 siblings, 1 reply; 4+ messages in thread
From: Sebastian Andrzej Siewior @ 2020-11-19 10:31 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, Thomas Gleixner, Cliff Whickman, Arnd Bergmann,
	Robin Holt, Steve Wahl, Dimitri Sivanich, Russ Anderson

From: Thomas Gleixner <tglx@linutronix.de>

The usage of in_interrupt() in xpc_partition_disengaged() is clearly
intended to avoid canceling the timeout timer when the function is invoked
from the timer callback.

While in_interrupt() is deprecated and ill defined as it does not provide
what the name suggests it catches the intended case.

Add an argument to xpc_partition_disengaged() which is true if called
from timer and otherwise false.
Use del_timer_sync() instead of del_singleshot_timer_sync() which is the
same thing.

Note: This does not prevent reentrancy into the function as the function
has no concurrency control and timer callback and regular task context
callers can happen concurrently on different CPUs or the timer can
interrupt the task context before it is able to cancel it.

While the only driver which is providing the arch_xpc_ops callbacks
(xpc_uv) seems not to have a reentrancy problem and the only negative
effect would be a double dev_info() entry in dmesg, the whole mechanism is
conceptually broken.

But that's not subject of this cleanup endeavour and left as an exercise to
the folks who might have interest to make that code fully correct.

[bigeasy: Add the argument, use del_timer_sync().]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Cliff Whickman <cpw@sgi.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Robin Holt <robinmholt@gmail.com>
Cc: Steve Wahl <steve.wahl@hpe.com>
Cc: Dimitri Sivanich <dimitri.sivanich@hpe.com>
Cc: Russ Anderson <russ.anderson@hpe.com>
---
v1…v2: Use xpc_partition_disengaged_from_timer() and don't export the
       argument. Suggested by Greg.

 drivers/misc/sgi-xp/xpc.h           |  1 +
 drivers/misc/sgi-xp/xpc_main.c      |  2 +-
 drivers/misc/sgi-xp/xpc_partition.c | 20 +++++++++++++++-----
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
index 71db60edff655..225f2bb84e39b 100644
--- a/drivers/misc/sgi-xp/xpc.h
+++ b/drivers/misc/sgi-xp/xpc.h
@@ -634,6 +634,7 @@ extern int xpc_setup_rsvd_page(void);
 extern void xpc_teardown_rsvd_page(void);
 extern int xpc_identify_activate_IRQ_sender(void);
 extern int xpc_partition_disengaged(struct xpc_partition *);
+extern int xpc_partition_disengaged_from_timer(struct xpc_partition *part);
 extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
 extern void xpc_mark_partition_inactive(struct xpc_partition *);
 extern void xpc_discovery(void);
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index e5244fc1dab30..84610bbcc1314 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -179,7 +179,7 @@ xpc_timeout_partition_disengage(struct timer_list *t)
 
 	DBUG_ON(time_is_after_jiffies(part->disengage_timeout));
 
-	(void)xpc_partition_disengaged(part);
+	xpc_partition_disengaged_from_timer(part);
 
 	DBUG_ON(part->disengage_timeout != 0);
 	DBUG_ON(xpc_arch_ops.partition_engaged(XPC_PARTID(part)));
diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c
index 57df06820bae2..1999d02923dee 100644
--- a/drivers/misc/sgi-xp/xpc_partition.c
+++ b/drivers/misc/sgi-xp/xpc_partition.c
@@ -262,8 +262,8 @@ xpc_get_remote_rp(int nasid, unsigned long *discovered_nasids,
  * from us. Though we requested the remote partition to deactivate with regard
  * to us, we really only need to wait for the other side to disengage from us.
  */
-int
-xpc_partition_disengaged(struct xpc_partition *part)
+static int __xpc_partition_disengaged(struct xpc_partition *part,
+				      bool from_timer)
 {
 	short partid = XPC_PARTID(part);
 	int disengaged;
@@ -289,9 +289,9 @@ xpc_partition_disengaged(struct xpc_partition *part)
 		}
 		part->disengage_timeout = 0;
 
-		/* cancel the timer function, provided it's not us */
-		if (!in_interrupt())
-			del_singleshot_timer_sync(&part->disengage_timer);
+		/* Cancel the timer function if not called from it */
+		if (!from_timer)
+			del_timer_sync(&part->disengage_timer);
 
 		DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING &&
 			part->act_state != XPC_P_AS_INACTIVE);
@@ -303,6 +303,16 @@ xpc_partition_disengaged(struct xpc_partition *part)
 	return disengaged;
 }
 
+int xpc_partition_disengaged(struct xpc_partition *part)
+{
+	return __xpc_partition_disengaged(part, false);
+}
+
+int xpc_partition_disengaged_from_timer(struct xpc_partition *part)
+{
+	return __xpc_partition_disengaged(part, true);
+}
+
 /*
  * Mark specified partition as active.
  */
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] misc/sgi-xp: Replace in_interrupt() usage
  2020-11-19 10:31   ` [PATCH v2] " Sebastian Andrzej Siewior
@ 2020-11-19 16:11     ` Steve Wahl
  0 siblings, 0 replies; 4+ messages in thread
From: Steve Wahl @ 2020-11-19 16:11 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: Greg Kroah-Hartman, linux-kernel, Thomas Gleixner, Arnd Bergmann,
	Robin Holt, Steve Wahl, Dimitri Sivanich, Russ Anderson

Reviewed-by: Steve Wahl <steve.wahl@hpe.com>

On Thu, Nov 19, 2020 at 11:31:51AM +0100, Sebastian Andrzej Siewior wrote:
> From: Thomas Gleixner <tglx@linutronix.de>
> 
> The usage of in_interrupt() in xpc_partition_disengaged() is clearly
> intended to avoid canceling the timeout timer when the function is invoked
> from the timer callback.
> 
> While in_interrupt() is deprecated and ill defined as it does not provide
> what the name suggests it catches the intended case.
> 
> Add an argument to xpc_partition_disengaged() which is true if called
> from timer and otherwise false.
> Use del_timer_sync() instead of del_singleshot_timer_sync() which is the
> same thing.
> 
> Note: This does not prevent reentrancy into the function as the function
> has no concurrency control and timer callback and regular task context
> callers can happen concurrently on different CPUs or the timer can
> interrupt the task context before it is able to cancel it.
> 
> While the only driver which is providing the arch_xpc_ops callbacks
> (xpc_uv) seems not to have a reentrancy problem and the only negative
> effect would be a double dev_info() entry in dmesg, the whole mechanism is
> conceptually broken.
> 
> But that's not subject of this cleanup endeavour and left as an exercise to
> the folks who might have interest to make that code fully correct.
> 
> [bigeasy: Add the argument, use del_timer_sync().]
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Cliff Whickman <cpw@sgi.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Robin Holt <robinmholt@gmail.com>
> Cc: Steve Wahl <steve.wahl@hpe.com>
> Cc: Dimitri Sivanich <dimitri.sivanich@hpe.com>
> Cc: Russ Anderson <russ.anderson@hpe.com>
> ---
> v1…v2: Use xpc_partition_disengaged_from_timer() and don't export the
>        argument. Suggested by Greg.
> 
>  drivers/misc/sgi-xp/xpc.h           |  1 +
>  drivers/misc/sgi-xp/xpc_main.c      |  2 +-
>  drivers/misc/sgi-xp/xpc_partition.c | 20 +++++++++++++++-----
>  3 files changed, 17 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
> index 71db60edff655..225f2bb84e39b 100644
> --- a/drivers/misc/sgi-xp/xpc.h
> +++ b/drivers/misc/sgi-xp/xpc.h
> @@ -634,6 +634,7 @@ extern int xpc_setup_rsvd_page(void);
>  extern void xpc_teardown_rsvd_page(void);
>  extern int xpc_identify_activate_IRQ_sender(void);
>  extern int xpc_partition_disengaged(struct xpc_partition *);
> +extern int xpc_partition_disengaged_from_timer(struct xpc_partition *part);
>  extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
>  extern void xpc_mark_partition_inactive(struct xpc_partition *);
>  extern void xpc_discovery(void);
> diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
> index e5244fc1dab30..84610bbcc1314 100644
> --- a/drivers/misc/sgi-xp/xpc_main.c
> +++ b/drivers/misc/sgi-xp/xpc_main.c
> @@ -179,7 +179,7 @@ xpc_timeout_partition_disengage(struct timer_list *t)
>  
>  	DBUG_ON(time_is_after_jiffies(part->disengage_timeout));
>  
> -	(void)xpc_partition_disengaged(part);
> +	xpc_partition_disengaged_from_timer(part);
>  
>  	DBUG_ON(part->disengage_timeout != 0);
>  	DBUG_ON(xpc_arch_ops.partition_engaged(XPC_PARTID(part)));
> diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c
> index 57df06820bae2..1999d02923dee 100644
> --- a/drivers/misc/sgi-xp/xpc_partition.c
> +++ b/drivers/misc/sgi-xp/xpc_partition.c
> @@ -262,8 +262,8 @@ xpc_get_remote_rp(int nasid, unsigned long *discovered_nasids,
>   * from us. Though we requested the remote partition to deactivate with regard
>   * to us, we really only need to wait for the other side to disengage from us.
>   */
> -int
> -xpc_partition_disengaged(struct xpc_partition *part)
> +static int __xpc_partition_disengaged(struct xpc_partition *part,
> +				      bool from_timer)
>  {
>  	short partid = XPC_PARTID(part);
>  	int disengaged;
> @@ -289,9 +289,9 @@ xpc_partition_disengaged(struct xpc_partition *part)
>  		}
>  		part->disengage_timeout = 0;
>  
> -		/* cancel the timer function, provided it's not us */
> -		if (!in_interrupt())
> -			del_singleshot_timer_sync(&part->disengage_timer);
> +		/* Cancel the timer function if not called from it */
> +		if (!from_timer)
> +			del_timer_sync(&part->disengage_timer);
>  
>  		DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING &&
>  			part->act_state != XPC_P_AS_INACTIVE);
> @@ -303,6 +303,16 @@ xpc_partition_disengaged(struct xpc_partition *part)
>  	return disengaged;
>  }
>  
> +int xpc_partition_disengaged(struct xpc_partition *part)
> +{
> +	return __xpc_partition_disengaged(part, false);
> +}
> +
> +int xpc_partition_disengaged_from_timer(struct xpc_partition *part)
> +{
> +	return __xpc_partition_disengaged(part, true);
> +}
> +
>  /*
>   * Mark specified partition as active.
>   */
> -- 
> 2.29.2
> 

-- 
Steve Wahl, Hewlett Packard Enterprise

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-11-19 16:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-19  8:13 [PATCH] misc/sgi-xp: Replace in_interrupt() usage Sebastian Andrzej Siewior
2020-11-19  8:44 ` Greg Kroah-Hartman
2020-11-19 10:31   ` [PATCH v2] " Sebastian Andrzej Siewior
2020-11-19 16:11     ` Steve Wahl

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).