diff mbox series

[net,2/3] net: ipa: use state to determine channel command success

Message ID 20201222180012.22489-3-elder@linaro.org
State New
Headers show
Series net: ipa: GSI interrupt handling fixes | expand

Commit Message

Alex Elder Dec. 22, 2020, 6 p.m. UTC
The result of issuing a channel control command should be that the
channel changes state.  If enabled, a completion interrupt signals
that the channel state has changed.  This interrupt is enabled by
gsi_channel_command() and disabled again after the command has
completed (or we time out).

There is a window of time--after the completion interrupt is disabled
but before the channel state is read--during which the command could
complete successfully without interrupting.  This would cause the
channel to transition to the desired new state.

So whether a channel command ends via completion interrupt or
timeout, we can consider the command successful if the channel
has entered the desired state (and a failure if it has not,
regardless of the cause).

Fixes: d6c9e3f506ae8 ("net: ipa: only enable generic command completion IRQ when needed");
Signed-off-by: Alex Elder <elder@linaro.org>

---
 drivers/net/ipa/gsi.c | 43 ++++++++++++++++++++++---------------------
 1 file changed, 22 insertions(+), 21 deletions(-)

-- 
2.20.1

Comments

kernel test robot Dec. 26, 2020, 6:51 p.m. UTC | #1
Hi Alex,

I love your patch! Perhaps something to improve:

[auto build test WARNING on net/master]

url:    https://github.com/0day-ci/linux/commits/Alex-Elder/net-ipa-GSI-interrupt-handling-fixes/20201223-020409
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git 2575bc1aa9d52a62342b57a0b7d0a12146cf6aed
config: arm64-allyesconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/4073b68cee8a9d0dbb83080db22255fc9b9d7fd5
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Alex-Elder/net-ipa-GSI-interrupt-handling-fixes/20201223-020409
        git checkout 4073b68cee8a9d0dbb83080db22255fc9b9d7fd5
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/net/ipa/gsi.c: In function 'gsi_channel_alloc_command':
>> drivers/net/ipa/gsi.c:496:6: warning: variable 'ret' set but not used [-Wunused-but-set-variable]

     496 |  int ret;
         |      ^~~
   drivers/net/ipa/gsi.c: In function 'gsi_channel_start_command':
   drivers/net/ipa/gsi.c:524:6: warning: variable 'ret' set but not used [-Wunused-but-set-variable]
     524 |  int ret;
         |      ^~~
   drivers/net/ipa/gsi.c: In function 'gsi_channel_stop_command':
   drivers/net/ipa/gsi.c:552:6: warning: variable 'ret' set but not used [-Wunused-but-set-variable]
     552 |  int ret;
         |      ^~~
   drivers/net/ipa/gsi.c: In function 'gsi_channel_reset_command':
   drivers/net/ipa/gsi.c:591:6: warning: variable 'ret' set but not used [-Wunused-but-set-variable]
     591 |  int ret;
         |      ^~~
   drivers/net/ipa/gsi.c: In function 'gsi_channel_de_alloc_command':
   drivers/net/ipa/gsi.c:620:6: warning: variable 'ret' set but not used [-Wunused-but-set-variable]
     620 |  int ret;
         |      ^~~


vim +/ret +496 drivers/net/ipa/gsi.c

650d1603825d8ba Alex Elder 2020-03-05  489  
650d1603825d8ba Alex Elder 2020-03-05  490  /* Allocate GSI channel in NOT_ALLOCATED state */
650d1603825d8ba Alex Elder 2020-03-05  491  static int gsi_channel_alloc_command(struct gsi *gsi, u32 channel_id)
650d1603825d8ba Alex Elder 2020-03-05  492  {
650d1603825d8ba Alex Elder 2020-03-05  493  	struct gsi_channel *channel = &gsi->channel[channel_id];
a442b3c7554898f Alex Elder 2020-06-30  494  	struct device *dev = gsi->dev;
a2003b303875b41 Alex Elder 2020-04-30  495  	enum gsi_channel_state state;
650d1603825d8ba Alex Elder 2020-03-05 @496  	int ret;
650d1603825d8ba Alex Elder 2020-03-05  497  
650d1603825d8ba Alex Elder 2020-03-05  498  	/* Get initial channel state */
a2003b303875b41 Alex Elder 2020-04-30  499  	state = gsi_channel_state(channel);
a442b3c7554898f Alex Elder 2020-06-30  500  	if (state != GSI_CHANNEL_STATE_NOT_ALLOCATED) {
f8d3bdd561a7c95 Alex Elder 2020-11-19  501  		dev_err(dev, "channel %u bad state %u before alloc\n",
f8d3bdd561a7c95 Alex Elder 2020-11-19  502  			channel_id, state);
650d1603825d8ba Alex Elder 2020-03-05  503  		return -EINVAL;
a442b3c7554898f Alex Elder 2020-06-30  504  	}
650d1603825d8ba Alex Elder 2020-03-05  505  
650d1603825d8ba Alex Elder 2020-03-05  506  	ret = gsi_channel_command(channel, GSI_CH_ALLOCATE);
a2003b303875b41 Alex Elder 2020-04-30  507  
4073b68cee8a9d0 Alex Elder 2020-12-22  508  	/* If successful the channel state will have changed */
a2003b303875b41 Alex Elder 2020-04-30  509  	state = gsi_channel_state(channel);
4073b68cee8a9d0 Alex Elder 2020-12-22  510  	if (state == GSI_CHANNEL_STATE_ALLOCATED)
4073b68cee8a9d0 Alex Elder 2020-12-22  511  		return 0;
4073b68cee8a9d0 Alex Elder 2020-12-22  512  
f8d3bdd561a7c95 Alex Elder 2020-11-19  513  	dev_err(dev, "channel %u bad state %u after alloc\n",
f8d3bdd561a7c95 Alex Elder 2020-11-19  514  		channel_id, state);
650d1603825d8ba Alex Elder 2020-03-05  515  
4073b68cee8a9d0 Alex Elder 2020-12-22  516  	return -EIO;
650d1603825d8ba Alex Elder 2020-03-05  517  }
650d1603825d8ba Alex Elder 2020-03-05  518  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c
index 4aee60d62ab09..4f0e791764237 100644
--- a/drivers/net/ipa/gsi.c
+++ b/drivers/net/ipa/gsi.c
@@ -505,15 +505,15 @@  static int gsi_channel_alloc_command(struct gsi *gsi, u32 channel_id)
 
 	ret = gsi_channel_command(channel, GSI_CH_ALLOCATE);
 
-	/* Channel state will normally have been updated */
+	/* If successful the channel state will have changed */
 	state = gsi_channel_state(channel);
-	if (!ret && state != GSI_CHANNEL_STATE_ALLOCATED) {
-		dev_err(dev, "channel %u bad state %u after alloc\n",
-			channel_id, state);
-		ret = -EIO;
-	}
+	if (state == GSI_CHANNEL_STATE_ALLOCATED)
+		return 0;
 
-	return ret;
+	dev_err(dev, "channel %u bad state %u after alloc\n",
+		channel_id, state);
+
+	return -EIO;
 }
 
 /* Start an ALLOCATED channel */
@@ -533,15 +533,15 @@  static int gsi_channel_start_command(struct gsi_channel *channel)
 
 	ret = gsi_channel_command(channel, GSI_CH_START);
 
-	/* Channel state will normally have been updated */
+	/* If successful the channel state will have changed */
 	state = gsi_channel_state(channel);
-	if (!ret && state != GSI_CHANNEL_STATE_STARTED) {
-		dev_err(dev, "channel %u bad state %u after start\n",
-			gsi_channel_id(channel), state);
-		ret = -EIO;
-	}
+	if (state == GSI_CHANNEL_STATE_STARTED)
+		return 0;
 
-	return ret;
+	dev_err(dev, "channel %u bad state %u after start\n",
+		gsi_channel_id(channel), state);
+
+	return -EIO;
 }
 
 /* Stop a GSI channel in STARTED state */
@@ -568,10 +568,10 @@  static int gsi_channel_stop_command(struct gsi_channel *channel)
 
 	ret = gsi_channel_command(channel, GSI_CH_STOP);
 
-	/* Channel state will normally have been updated */
+	/* If successful the channel state will have changed */
 	state = gsi_channel_state(channel);
-	if (ret || state == GSI_CHANNEL_STATE_STOPPED)
-		return ret;
+	if (state == GSI_CHANNEL_STATE_STOPPED)
+		return 0;
 
 	/* We may have to try again if stop is in progress */
 	if (state == GSI_CHANNEL_STATE_STOP_IN_PROC)
@@ -604,9 +604,9 @@  static void gsi_channel_reset_command(struct gsi_channel *channel)
 
 	ret = gsi_channel_command(channel, GSI_CH_RESET);
 
-	/* Channel state will normally have been updated */
+	/* If successful the channel state will have changed */
 	state = gsi_channel_state(channel);
-	if (!ret && state != GSI_CHANNEL_STATE_ALLOCATED)
+	if (state != GSI_CHANNEL_STATE_ALLOCATED)
 		dev_err(dev, "channel %u bad state %u after reset\n",
 			gsi_channel_id(channel), state);
 }
@@ -628,9 +628,10 @@  static void gsi_channel_de_alloc_command(struct gsi *gsi, u32 channel_id)
 
 	ret = gsi_channel_command(channel, GSI_CH_DE_ALLOC);
 
-	/* Channel state will normally have been updated */
+	/* If successful the channel state will have changed */
 	state = gsi_channel_state(channel);
-	if (!ret && state != GSI_CHANNEL_STATE_NOT_ALLOCATED)
+
+	if (state != GSI_CHANNEL_STATE_NOT_ALLOCATED)
 		dev_err(dev, "channel %u bad state %u after dealloc\n",
 			channel_id, state);
 }