Commit 2d38c580 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'ionic-updates'

Shannon Nelson says:

====================
ionic updates

These updates are a bit of code cleaning and a minor
bit of performance tweaking.

v3: convert ionic_lif_quiesce() to void
v2: added void cast on call to ionic_lif_quiesce()
    lowered batching threshold
    added patch to flatten calls to ionic_lif_rx_mode
    added patch to change from_ndo to can_sleep
====================

Link: https://lore.kernel.org/r/20201112182208.46770-1-snelson@pensando.ioSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 9e6cad53 7c8d008c
...@@ -25,7 +25,7 @@ static void ionic_watchdog_cb(struct timer_list *t) ...@@ -25,7 +25,7 @@ static void ionic_watchdog_cb(struct timer_list *t)
hb = ionic_heartbeat_check(ionic); hb = ionic_heartbeat_check(ionic);
if (hb >= 0) if (hb >= 0)
ionic_link_status_check_request(ionic->lif, false); ionic_link_status_check_request(ionic->lif, CAN_NOT_SLEEP);
} }
void ionic_init_devinfo(struct ionic *ionic) void ionic_init_devinfo(struct ionic *ionic)
......
...@@ -12,8 +12,10 @@ ...@@ -12,8 +12,10 @@
#define IONIC_MAX_TX_DESC 8192 #define IONIC_MAX_TX_DESC 8192
#define IONIC_MAX_RX_DESC 16384 #define IONIC_MAX_RX_DESC 16384
#define IONIC_MIN_TXRX_DESC 16 #define IONIC_MIN_TXRX_DESC 64
#define IONIC_DEF_TXRX_DESC 4096 #define IONIC_DEF_TXRX_DESC 4096
#define IONIC_RX_FILL_THRESHOLD 16
#define IONIC_RX_FILL_DIV 8
#define IONIC_LIFS_MAX 1024 #define IONIC_LIFS_MAX 1024
#define IONIC_WATCHDOG_SECS 5 #define IONIC_WATCHDOG_SECS 5
#define IONIC_ITR_COAL_USEC_DEFAULT 64 #define IONIC_ITR_COAL_USEC_DEFAULT 64
......
...@@ -123,6 +123,12 @@ static void ionic_link_status_check(struct ionic_lif *lif) ...@@ -123,6 +123,12 @@ static void ionic_link_status_check(struct ionic_lif *lif)
link_up = link_status == IONIC_PORT_OPER_STATUS_UP; link_up = link_status == IONIC_PORT_OPER_STATUS_UP;
if (link_up) { if (link_up) {
if (lif->netdev->flags & IFF_UP && netif_running(lif->netdev)) {
mutex_lock(&lif->queue_lock);
ionic_start_queues(lif);
mutex_unlock(&lif->queue_lock);
}
if (!netif_carrier_ok(netdev)) { if (!netif_carrier_ok(netdev)) {
u32 link_speed; u32 link_speed;
...@@ -132,12 +138,6 @@ static void ionic_link_status_check(struct ionic_lif *lif) ...@@ -132,12 +138,6 @@ static void ionic_link_status_check(struct ionic_lif *lif)
link_speed / 1000); link_speed / 1000);
netif_carrier_on(netdev); netif_carrier_on(netdev);
} }
if (lif->netdev->flags & IFF_UP && netif_running(lif->netdev)) {
mutex_lock(&lif->queue_lock);
ionic_start_queues(lif);
mutex_unlock(&lif->queue_lock);
}
} else { } else {
if (netif_carrier_ok(netdev)) { if (netif_carrier_ok(netdev)) {
netdev_info(netdev, "Link down\n"); netdev_info(netdev, "Link down\n");
...@@ -1074,22 +1074,22 @@ static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add, ...@@ -1074,22 +1074,22 @@ static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add,
static int ionic_addr_add(struct net_device *netdev, const u8 *addr) static int ionic_addr_add(struct net_device *netdev, const u8 *addr)
{ {
return ionic_lif_addr(netdev_priv(netdev), addr, true, true); return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR, CAN_SLEEP);
} }
static int ionic_ndo_addr_add(struct net_device *netdev, const u8 *addr) static int ionic_ndo_addr_add(struct net_device *netdev, const u8 *addr)
{ {
return ionic_lif_addr(netdev_priv(netdev), addr, true, false); return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR, CAN_NOT_SLEEP);
} }
static int ionic_addr_del(struct net_device *netdev, const u8 *addr) static int ionic_addr_del(struct net_device *netdev, const u8 *addr)
{ {
return ionic_lif_addr(netdev_priv(netdev), addr, false, true); return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR, CAN_SLEEP);
} }
static int ionic_ndo_addr_del(struct net_device *netdev, const u8 *addr) static int ionic_ndo_addr_del(struct net_device *netdev, const u8 *addr)
{ {
return ionic_lif_addr(netdev_priv(netdev), addr, false, false); return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR, CAN_NOT_SLEEP);
} }
static void ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode) static void ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode)
...@@ -1129,38 +1129,10 @@ static void ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode) ...@@ -1129,38 +1129,10 @@ static void ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode)
lif->rx_mode = rx_mode; lif->rx_mode = rx_mode;
} }
static void _ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode, static void ionic_set_rx_mode(struct net_device *netdev, bool can_sleep)
bool from_ndo)
{
struct ionic_deferred_work *work;
if (from_ndo) {
work = kzalloc(sizeof(*work), GFP_ATOMIC);
if (!work) {
netdev_err(lif->netdev, "%s OOM\n", __func__);
return;
}
work->type = IONIC_DW_TYPE_RX_MODE;
work->rx_mode = rx_mode;
netdev_dbg(lif->netdev, "deferred: rx_mode\n");
ionic_lif_deferred_enqueue(&lif->deferred, work);
} else {
ionic_lif_rx_mode(lif, rx_mode);
}
}
static void ionic_dev_uc_sync(struct net_device *netdev, bool from_ndo)
{
if (from_ndo)
__dev_uc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
else
__dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del);
}
static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo)
{ {
struct ionic_lif *lif = netdev_priv(netdev); struct ionic_lif *lif = netdev_priv(netdev);
struct ionic_deferred_work *work;
unsigned int nfilters; unsigned int nfilters;
unsigned int rx_mode; unsigned int rx_mode;
...@@ -1177,7 +1149,10 @@ static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo) ...@@ -1177,7 +1149,10 @@ static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo)
* we remove our overflow flag and check the netdev flags * we remove our overflow flag and check the netdev flags
* to see if we can disable NIC PROMISC * to see if we can disable NIC PROMISC
*/ */
ionic_dev_uc_sync(netdev, from_ndo); if (can_sleep)
__dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del);
else
__dev_uc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters); nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters);
if (netdev_uc_count(netdev) + 1 > nfilters) { if (netdev_uc_count(netdev) + 1 > nfilters) {
rx_mode |= IONIC_RX_MODE_F_PROMISC; rx_mode |= IONIC_RX_MODE_F_PROMISC;
...@@ -1189,7 +1164,10 @@ static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo) ...@@ -1189,7 +1164,10 @@ static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo)
} }
/* same for multicast */ /* same for multicast */
ionic_dev_uc_sync(netdev, from_ndo); if (can_sleep)
__dev_mc_sync(netdev, ionic_addr_add, ionic_addr_del);
else
__dev_mc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
nfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters); nfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters);
if (netdev_mc_count(netdev) > nfilters) { if (netdev_mc_count(netdev) > nfilters) {
rx_mode |= IONIC_RX_MODE_F_ALLMULTI; rx_mode |= IONIC_RX_MODE_F_ALLMULTI;
...@@ -1200,13 +1178,26 @@ static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo) ...@@ -1200,13 +1178,26 @@ static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo)
rx_mode &= ~IONIC_RX_MODE_F_ALLMULTI; rx_mode &= ~IONIC_RX_MODE_F_ALLMULTI;
} }
if (lif->rx_mode != rx_mode) if (lif->rx_mode != rx_mode) {
_ionic_lif_rx_mode(lif, rx_mode, from_ndo); if (!can_sleep) {
work = kzalloc(sizeof(*work), GFP_ATOMIC);
if (!work) {
netdev_err(lif->netdev, "%s OOM\n", __func__);
return;
}
work->type = IONIC_DW_TYPE_RX_MODE;
work->rx_mode = rx_mode;
netdev_dbg(lif->netdev, "deferred: rx_mode\n");
ionic_lif_deferred_enqueue(&lif->deferred, work);
} else {
ionic_lif_rx_mode(lif, rx_mode);
}
}
} }
static void ionic_ndo_set_rx_mode(struct net_device *netdev) static void ionic_ndo_set_rx_mode(struct net_device *netdev)
{ {
ionic_set_rx_mode(netdev, true); ionic_set_rx_mode(netdev, CAN_NOT_SLEEP);
} }
static __le64 ionic_netdev_features_to_nic(netdev_features_t features) static __le64 ionic_netdev_features_to_nic(netdev_features_t features)
...@@ -1625,6 +1616,24 @@ static void ionic_lif_rss_deinit(struct ionic_lif *lif) ...@@ -1625,6 +1616,24 @@ static void ionic_lif_rss_deinit(struct ionic_lif *lif)
ionic_lif_rss_config(lif, 0x0, NULL, NULL); ionic_lif_rss_config(lif, 0x0, NULL, NULL);
} }
static void ionic_lif_quiesce(struct ionic_lif *lif)
{
struct ionic_admin_ctx ctx = {
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
.cmd.lif_setattr = {
.opcode = IONIC_CMD_LIF_SETATTR,
.index = cpu_to_le16(lif->index),
.attr = IONIC_LIF_ATTR_STATE,
.state = IONIC_LIF_QUIESCE,
},
};
int err;
err = ionic_adminq_post_wait(lif, &ctx);
if (err)
netdev_err(lif->netdev, "lif quiesce failed %d\n", err);
}
static void ionic_txrx_disable(struct ionic_lif *lif) static void ionic_txrx_disable(struct ionic_lif *lif)
{ {
unsigned int i; unsigned int i;
...@@ -1639,6 +1648,8 @@ static void ionic_txrx_disable(struct ionic_lif *lif) ...@@ -1639,6 +1648,8 @@ static void ionic_txrx_disable(struct ionic_lif *lif)
for (i = 0; i < lif->nxqs; i++) for (i = 0; i < lif->nxqs; i++)
err = ionic_qcq_disable(lif->rxqcqs[i], (err != -ETIMEDOUT)); err = ionic_qcq_disable(lif->rxqcqs[i], (err != -ETIMEDOUT));
} }
ionic_lif_quiesce(lif);
} }
static void ionic_txrx_deinit(struct ionic_lif *lif) static void ionic_txrx_deinit(struct ionic_lif *lif)
...@@ -1773,7 +1784,7 @@ static int ionic_txrx_init(struct ionic_lif *lif) ...@@ -1773,7 +1784,7 @@ static int ionic_txrx_init(struct ionic_lif *lif)
if (lif->netdev->features & NETIF_F_RXHASH) if (lif->netdev->features & NETIF_F_RXHASH)
ionic_lif_rss_init(lif); ionic_lif_rss_init(lif);
ionic_set_rx_mode(lif->netdev, false); ionic_set_rx_mode(lif->netdev, CAN_SLEEP);
return 0; return 0;
...@@ -2781,7 +2792,7 @@ static int ionic_station_set(struct ionic_lif *lif) ...@@ -2781,7 +2792,7 @@ static int ionic_station_set(struct ionic_lif *lif)
*/ */
if (!ether_addr_equal(ctx.comp.lif_getattr.mac, if (!ether_addr_equal(ctx.comp.lif_getattr.mac,
netdev->dev_addr)) netdev->dev_addr))
ionic_lif_addr(lif, netdev->dev_addr, true, true); ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR, CAN_SLEEP);
} else { } else {
/* Update the netdev mac with the device's mac */ /* Update the netdev mac with the device's mac */
memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len); memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len);
...@@ -2798,7 +2809,7 @@ static int ionic_station_set(struct ionic_lif *lif) ...@@ -2798,7 +2809,7 @@ static int ionic_station_set(struct ionic_lif *lif)
netdev_dbg(lif->netdev, "adding station MAC addr %pM\n", netdev_dbg(lif->netdev, "adding station MAC addr %pM\n",
netdev->dev_addr); netdev->dev_addr);
ionic_lif_addr(lif, netdev->dev_addr, true, true); ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR, CAN_SLEEP);
return 0; return 0;
} }
...@@ -2959,6 +2970,8 @@ int ionic_lif_register(struct ionic_lif *lif) ...@@ -2959,6 +2970,8 @@ int ionic_lif_register(struct ionic_lif *lif)
dev_err(lif->ionic->dev, "Cannot register net device, aborting\n"); dev_err(lif->ionic->dev, "Cannot register net device, aborting\n");
return err; return err;
} }
ionic_link_status_check_request(lif, true);
lif->registered = true; lif->registered = true;
ionic_lif_set_netdev_info(lif); ionic_lif_set_netdev_info(lif);
......
...@@ -13,6 +13,12 @@ ...@@ -13,6 +13,12 @@
#define IONIC_MAX_NUM_NAPI_CNTR (NAPI_POLL_WEIGHT + 1) #define IONIC_MAX_NUM_NAPI_CNTR (NAPI_POLL_WEIGHT + 1)
#define IONIC_MAX_NUM_SG_CNTR (IONIC_TX_MAX_SG_ELEMS + 1) #define IONIC_MAX_NUM_SG_CNTR (IONIC_TX_MAX_SG_ELEMS + 1)
#define ADD_ADDR true
#define DEL_ADDR false
#define CAN_SLEEP true
#define CAN_NOT_SLEEP false
#define IONIC_RX_COPYBREAK_DEFAULT 256 #define IONIC_RX_COPYBREAK_DEFAULT 256
#define IONIC_TX_BUDGET_DEFAULT 256 #define IONIC_TX_BUDGET_DEFAULT 256
......
...@@ -392,11 +392,6 @@ void ionic_rx_fill(struct ionic_queue *q) ...@@ -392,11 +392,6 @@ void ionic_rx_fill(struct ionic_queue *q)
q->dbval | q->head_idx); q->dbval | q->head_idx);
} }
static void ionic_rx_fill_cb(void *arg)
{
ionic_rx_fill(arg);
}
void ionic_rx_empty(struct ionic_queue *q) void ionic_rx_empty(struct ionic_queue *q)
{ {
struct ionic_desc_info *desc_info; struct ionic_desc_info *desc_info;
...@@ -480,6 +475,7 @@ int ionic_rx_napi(struct napi_struct *napi, int budget) ...@@ -480,6 +475,7 @@ int ionic_rx_napi(struct napi_struct *napi, int budget)
struct ionic_cq *cq = napi_to_cq(napi); struct ionic_cq *cq = napi_to_cq(napi);
struct ionic_dev *idev; struct ionic_dev *idev;
struct ionic_lif *lif; struct ionic_lif *lif;
u16 rx_fill_threshold;
u32 work_done = 0; u32 work_done = 0;
u32 flags = 0; u32 flags = 0;
...@@ -489,7 +485,9 @@ int ionic_rx_napi(struct napi_struct *napi, int budget) ...@@ -489,7 +485,9 @@ int ionic_rx_napi(struct napi_struct *napi, int budget)
work_done = ionic_cq_service(cq, budget, work_done = ionic_cq_service(cq, budget,
ionic_rx_service, NULL, NULL); ionic_rx_service, NULL, NULL);
if (work_done) rx_fill_threshold = min_t(u16, IONIC_RX_FILL_THRESHOLD,
cq->num_descs / IONIC_RX_FILL_DIV);
if (work_done && ionic_q_space_avail(cq->bound_q) >= rx_fill_threshold)
ionic_rx_fill(cq->bound_q); ionic_rx_fill(cq->bound_q);
if (work_done < budget && napi_complete_done(napi, work_done)) { if (work_done < budget && napi_complete_done(napi, work_done)) {
...@@ -518,6 +516,7 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget) ...@@ -518,6 +516,7 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget)
struct ionic_dev *idev; struct ionic_dev *idev;
struct ionic_lif *lif; struct ionic_lif *lif;
struct ionic_cq *txcq; struct ionic_cq *txcq;
u16 rx_fill_threshold;
u32 rx_work_done = 0; u32 rx_work_done = 0;
u32 tx_work_done = 0; u32 tx_work_done = 0;
u32 flags = 0; u32 flags = 0;
...@@ -531,8 +530,11 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget) ...@@ -531,8 +530,11 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget)
rx_work_done = ionic_cq_service(rxcq, budget, rx_work_done = ionic_cq_service(rxcq, budget,
ionic_rx_service, NULL, NULL); ionic_rx_service, NULL, NULL);
if (rx_work_done)
ionic_rx_fill_cb(rxcq->bound_q); rx_fill_threshold = min_t(u16, IONIC_RX_FILL_THRESHOLD,
rxcq->num_descs / IONIC_RX_FILL_DIV);
if (rx_work_done && ionic_q_space_avail(rxcq->bound_q) >= rx_fill_threshold)
ionic_rx_fill(rxcq->bound_q);
if (rx_work_done < budget && napi_complete_done(napi, rx_work_done)) { if (rx_work_done < budget && napi_complete_done(napi, rx_work_done)) {
ionic_dim_update(qcq); ionic_dim_update(qcq);
......
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