Commit 3f77c926 authored by Alex Elder's avatar Alex Elder Committed by Jakub Kicinski

net: ipa: do not cache event ring state

An event ring's state only needs to be known when it is allocated,
reset, or deallocated.  We check an event ring's state both before
and after performing an event ring control command that changes
its state.  These are only issued at startup and shutdown, so there
is very little value in caching the state.

Stop recording a copy of the channel's last known state, and instead
fetch the true state from hardware whenever it's needed.  In such
cases, *do* record the state in a local variable, in case an error
message reports it (so the value reported is the value seen).
Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent b1750723
...@@ -408,30 +408,31 @@ static void gsi_evt_ring_command(struct gsi *gsi, u32 evt_ring_id, ...@@ -408,30 +408,31 @@ static void gsi_evt_ring_command(struct gsi *gsi, u32 evt_ring_id,
return; return;
dev_err(dev, "GSI command %u for event ring %u timed out, state %u\n", dev_err(dev, "GSI command %u for event ring %u timed out, state %u\n",
opcode, evt_ring_id, evt_ring->state); opcode, evt_ring_id, gsi_evt_ring_state(gsi, evt_ring_id));
} }
/* Allocate an event ring in NOT_ALLOCATED state */ /* Allocate an event ring in NOT_ALLOCATED state */
static int gsi_evt_ring_alloc_command(struct gsi *gsi, u32 evt_ring_id) static int gsi_evt_ring_alloc_command(struct gsi *gsi, u32 evt_ring_id)
{ {
struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; enum gsi_evt_ring_state state;
/* Get initial event ring state */ /* Get initial event ring state */
evt_ring->state = gsi_evt_ring_state(gsi, evt_ring_id); state = gsi_evt_ring_state(gsi, evt_ring_id);
if (evt_ring->state != GSI_EVT_RING_STATE_NOT_ALLOCATED) { if (state != GSI_EVT_RING_STATE_NOT_ALLOCATED) {
dev_err(gsi->dev, "event ring %u bad state %u before alloc\n", dev_err(gsi->dev, "event ring %u bad state %u before alloc\n",
evt_ring_id, evt_ring->state); evt_ring_id, state);
return -EINVAL; return -EINVAL;
} }
gsi_evt_ring_command(gsi, evt_ring_id, GSI_EVT_ALLOCATE); gsi_evt_ring_command(gsi, evt_ring_id, GSI_EVT_ALLOCATE);
/* If successful the event ring state will have changed */ /* If successful the event ring state will have changed */
if (evt_ring->state == GSI_EVT_RING_STATE_ALLOCATED) state = gsi_evt_ring_state(gsi, evt_ring_id);
if (state == GSI_EVT_RING_STATE_ALLOCATED)
return 0; return 0;
dev_err(gsi->dev, "event ring %u bad state %u after alloc\n", dev_err(gsi->dev, "event ring %u bad state %u after alloc\n",
evt_ring_id, evt_ring->state); evt_ring_id, state);
return -EIO; return -EIO;
} }
...@@ -439,45 +440,48 @@ static int gsi_evt_ring_alloc_command(struct gsi *gsi, u32 evt_ring_id) ...@@ -439,45 +440,48 @@ static int gsi_evt_ring_alloc_command(struct gsi *gsi, u32 evt_ring_id)
/* Reset a GSI event ring in ALLOCATED or ERROR state. */ /* Reset a GSI event ring in ALLOCATED or ERROR state. */
static void gsi_evt_ring_reset_command(struct gsi *gsi, u32 evt_ring_id) static void gsi_evt_ring_reset_command(struct gsi *gsi, u32 evt_ring_id)
{ {
struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; enum gsi_evt_ring_state state;
enum gsi_evt_ring_state state = evt_ring->state;
state = gsi_evt_ring_state(gsi, evt_ring_id);
if (state != GSI_EVT_RING_STATE_ALLOCATED && if (state != GSI_EVT_RING_STATE_ALLOCATED &&
state != GSI_EVT_RING_STATE_ERROR) { state != GSI_EVT_RING_STATE_ERROR) {
dev_err(gsi->dev, "event ring %u bad state %u before reset\n", dev_err(gsi->dev, "event ring %u bad state %u before reset\n",
evt_ring_id, evt_ring->state); evt_ring_id, state);
return; return;
} }
gsi_evt_ring_command(gsi, evt_ring_id, GSI_EVT_RESET); gsi_evt_ring_command(gsi, evt_ring_id, GSI_EVT_RESET);
/* If successful the event ring state will have changed */ /* If successful the event ring state will have changed */
if (evt_ring->state == GSI_EVT_RING_STATE_ALLOCATED) state = gsi_evt_ring_state(gsi, evt_ring_id);
if (state == GSI_EVT_RING_STATE_ALLOCATED)
return; return;
dev_err(gsi->dev, "event ring %u bad state %u after reset\n", dev_err(gsi->dev, "event ring %u bad state %u after reset\n",
evt_ring_id, evt_ring->state); evt_ring_id, state);
} }
/* Issue a hardware de-allocation request for an allocated event ring */ /* Issue a hardware de-allocation request for an allocated event ring */
static void gsi_evt_ring_de_alloc_command(struct gsi *gsi, u32 evt_ring_id) static void gsi_evt_ring_de_alloc_command(struct gsi *gsi, u32 evt_ring_id)
{ {
struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; enum gsi_evt_ring_state state;
if (evt_ring->state != GSI_EVT_RING_STATE_ALLOCATED) { state = gsi_evt_ring_state(gsi, evt_ring_id);
if (state != GSI_EVT_RING_STATE_ALLOCATED) {
dev_err(gsi->dev, "event ring %u state %u before dealloc\n", dev_err(gsi->dev, "event ring %u state %u before dealloc\n",
evt_ring_id, evt_ring->state); evt_ring_id, state);
return; return;
} }
gsi_evt_ring_command(gsi, evt_ring_id, GSI_EVT_DE_ALLOC); gsi_evt_ring_command(gsi, evt_ring_id, GSI_EVT_DE_ALLOC);
/* If successful the event ring state will have changed */ /* If successful the event ring state will have changed */
if (evt_ring->state == GSI_EVT_RING_STATE_NOT_ALLOCATED) state = gsi_evt_ring_state(gsi, evt_ring_id);
if (state == GSI_EVT_RING_STATE_NOT_ALLOCATED)
return; return;
dev_err(gsi->dev, "event ring %u bad state %u after dealloc\n", dev_err(gsi->dev, "event ring %u bad state %u after dealloc\n",
evt_ring_id, evt_ring->state); evt_ring_id, state);
} }
/* Fetch the current state of a channel from hardware */ /* Fetch the current state of a channel from hardware */
...@@ -1107,7 +1111,6 @@ static void gsi_isr_evt_ctrl(struct gsi *gsi) ...@@ -1107,7 +1111,6 @@ static void gsi_isr_evt_ctrl(struct gsi *gsi)
event_mask ^= BIT(evt_ring_id); event_mask ^= BIT(evt_ring_id);
evt_ring = &gsi->evt_ring[evt_ring_id]; evt_ring = &gsi->evt_ring[evt_ring_id];
evt_ring->state = gsi_evt_ring_state(gsi, evt_ring_id);
complete(&evt_ring->completion); complete(&evt_ring->completion);
} }
......
...@@ -142,7 +142,6 @@ enum gsi_evt_ring_state { ...@@ -142,7 +142,6 @@ enum gsi_evt_ring_state {
struct gsi_evt_ring { struct gsi_evt_ring {
struct gsi_channel *channel; struct gsi_channel *channel;
struct completion completion; /* signals event ring state changes */ struct completion completion; /* signals event ring state changes */
enum gsi_evt_ring_state state;
struct gsi_ring ring; struct gsi_ring ring;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment