sunvnet: track port queues correctly

Track our used and unused queue indexies correctly.  Otherwise, as ports
dropped out and returned, they all eventually ended up with the same
queue index.

Orabug: 25190537

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Shannon Nelson 2017-03-14 10:24:41 -07:00 committed by David S. Miller
parent 0f512c8454
commit e1f1e5f711
2 changed files with 22 additions and 13 deletions

View File

@ -1728,11 +1728,25 @@ EXPORT_SYMBOL_GPL(sunvnet_poll_controller_common);
void sunvnet_port_add_txq_common(struct vnet_port *port) void sunvnet_port_add_txq_common(struct vnet_port *port)
{ {
struct vnet *vp = port->vp; struct vnet *vp = port->vp;
int n; int smallest = 0;
int i;
n = vp->nports++; /* find the first least-used q
n = n & (VNET_MAX_TXQS - 1); * When there are more ldoms than q's, we start to
port->q_index = n; * double up on ports per queue.
*/
for (i = 0; i < VNET_MAX_TXQS; i++) {
if (vp->q_used[i] == 0) {
smallest = i;
break;
}
if (vp->q_used[i] < vp->q_used[smallest])
smallest = i;
}
vp->nports++;
vp->q_used[smallest]++;
port->q_index = smallest;
netif_tx_wake_queue(netdev_get_tx_queue(VNET_PORT_TO_NET_DEVICE(port), netif_tx_wake_queue(netdev_get_tx_queue(VNET_PORT_TO_NET_DEVICE(port),
port->q_index)); port->q_index));
} }
@ -1743,5 +1757,7 @@ void sunvnet_port_rm_txq_common(struct vnet_port *port)
port->vp->nports--; port->vp->nports--;
netif_tx_stop_queue(netdev_get_tx_queue(VNET_PORT_TO_NET_DEVICE(port), netif_tx_stop_queue(netdev_get_tx_queue(VNET_PORT_TO_NET_DEVICE(port),
port->q_index)); port->q_index));
port->vp->q_used[port->q_index]--;
port->q_index = 0;
} }
EXPORT_SYMBOL_GPL(sunvnet_port_rm_txq_common); EXPORT_SYMBOL_GPL(sunvnet_port_rm_txq_common);

View File

@ -112,22 +112,15 @@ struct vnet_mcast_entry {
}; };
struct vnet { struct vnet {
/* Protects port_list and port_hash. */ spinlock_t lock; /* Protects port_list and port_hash. */
spinlock_t lock;
struct net_device *dev; struct net_device *dev;
u32 msg_enable; u32 msg_enable;
u8 q_used[VNET_MAX_TXQS];
struct list_head port_list; struct list_head port_list;
struct hlist_head port_hash[VNET_PORT_HASH_SIZE]; struct hlist_head port_hash[VNET_PORT_HASH_SIZE];
struct vnet_mcast_entry *mcast_list; struct vnet_mcast_entry *mcast_list;
struct list_head list; struct list_head list;
u64 local_mac; u64 local_mac;
int nports; int nports;
}; };