Commit 52b4c862 authored by Gavin Shan's avatar Gavin Shan Committed by David S. Miller

net/ncsi: Enforce failover on link monitor timeout

The NCSI channel has been configured to provide service if its link
monitor timer is enabled, regardless of its state (inactive or active).
So the timeout event on the link monitor indicates the out-of-service
on that channel, for which a failover is needed.

This sets NCSI_DEV_RESHUFFLE flag to enforce failover on link monitor
timeout, regardless the channel's original state (inactive or active).
Also, the link is put into "down" state to give the failing channel
lowest priority when selecting for the active channel. The state of
failing channel should be set to active in order for deinitialization
and failover to be done.
Signed-off-by: default avatarGavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: default avatarSamuel Mendoza-Jonas <sam@mendozajonas.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 100ef01f
...@@ -189,6 +189,7 @@ static void ncsi_channel_monitor(unsigned long data) ...@@ -189,6 +189,7 @@ static void ncsi_channel_monitor(unsigned long data)
struct ncsi_channel *nc = (struct ncsi_channel *)data; struct ncsi_channel *nc = (struct ncsi_channel *)data;
struct ncsi_package *np = nc->package; struct ncsi_package *np = nc->package;
struct ncsi_dev_priv *ndp = np->ndp; struct ncsi_dev_priv *ndp = np->ndp;
struct ncsi_channel_mode *ncm;
struct ncsi_cmd_arg nca; struct ncsi_cmd_arg nca;
bool enabled, chained; bool enabled, chained;
unsigned int monitor_state; unsigned int monitor_state;
...@@ -228,20 +229,21 @@ static void ncsi_channel_monitor(unsigned long data) ...@@ -228,20 +229,21 @@ static void ncsi_channel_monitor(unsigned long data)
case NCSI_CHANNEL_MONITOR_WAIT ... NCSI_CHANNEL_MONITOR_WAIT_MAX: case NCSI_CHANNEL_MONITOR_WAIT ... NCSI_CHANNEL_MONITOR_WAIT_MAX:
break; break;
default: default:
if (!(ndp->flags & NCSI_DEV_HWA) && if (!(ndp->flags & NCSI_DEV_HWA)) {
state == NCSI_CHANNEL_ACTIVE) {
ncsi_report_link(ndp, true); ncsi_report_link(ndp, true);
ndp->flags |= NCSI_DEV_RESHUFFLE; ndp->flags |= NCSI_DEV_RESHUFFLE;
} }
ncsi_stop_channel_monitor(nc); ncsi_stop_channel_monitor(nc);
ncm = &nc->modes[NCSI_MODE_LINK];
spin_lock_irqsave(&nc->lock, flags); spin_lock_irqsave(&nc->lock, flags);
nc->state = NCSI_CHANNEL_INVISIBLE; nc->state = NCSI_CHANNEL_INVISIBLE;
ncm->data[2] &= ~0x1;
spin_unlock_irqrestore(&nc->lock, flags); spin_unlock_irqrestore(&nc->lock, flags);
spin_lock_irqsave(&ndp->lock, flags); spin_lock_irqsave(&ndp->lock, flags);
nc->state = NCSI_CHANNEL_INACTIVE; nc->state = NCSI_CHANNEL_ACTIVE;
list_add_tail_rcu(&nc->link, &ndp->channel_queue); list_add_tail_rcu(&nc->link, &ndp->channel_queue);
spin_unlock_irqrestore(&ndp->lock, flags); spin_unlock_irqrestore(&ndp->lock, flags);
ncsi_process_next_channel(ndp); ncsi_process_next_channel(ndp);
......
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