Commit 5ce7f3f4 authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by Jakub Kicinski

net: neterion: s2io: Replace in_interrupt() for context detection

wait_for_cmd_complete() uses in_interrupt() to detect whether it is safe to
sleep or not.

The usage of in_interrupt() in drivers is phased out and Linus clearly
requested that code which changes behaviour depending on context should
either be seperated or the context be conveyed in an argument passed by the
caller, which usually knows the context.

in_interrupt() also is only partially correct because it fails to chose the
correct code path when just preemption or interrupts are disabled.

Add an argument 'may_block' to both functions and adjust the callers to
pass the context information.

The following call chains which end up invoking wait_for_cmd_complete()
were analyzed to be safe to sleep:

 s2io_card_up()
   s2io_set_multicast()

 init_nic()
   init_tti()

 s2io_close()
   do_s2io_delete_unicast_mc()
     do_s2io_add_mac()

 s2io_set_mac_addr()
   do_s2io_prog_unicast()
     do_s2io_add_mac()

 s2io_reset()
   do_s2io_restore_unicast_mc()
     do_s2io_add_mc()
       do_s2io_add_mac()

 s2io_open()
   do_s2io_prog_unicast()
     do_s2io_add_mac()

The following call chains which end up invoking wait_for_cmd_complete()
were analyzed to be safe to sleep:

 __dev_set_rx_mode()
    s2io_set_multicast()

 s2io_txpic_intr_handle()
   s2io_link()
     init_tti()

Add a may_sleep argument to wait_for_cmd_complete(), s2io_set_multicast()
and init_tti() and hand the context information in from the call sites.
Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Jon Mason <jdmason@kudzu.us>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 68bb4665
...@@ -1106,7 +1106,7 @@ static int s2io_print_pci_mode(struct s2io_nic *nic) ...@@ -1106,7 +1106,7 @@ static int s2io_print_pci_mode(struct s2io_nic *nic)
* '-1' on failure * '-1' on failure
*/ */
static int init_tti(struct s2io_nic *nic, int link) static int init_tti(struct s2io_nic *nic, int link, bool may_sleep)
{ {
struct XENA_dev_config __iomem *bar0 = nic->bar0; struct XENA_dev_config __iomem *bar0 = nic->bar0;
register u64 val64 = 0; register u64 val64 = 0;
...@@ -1166,7 +1166,7 @@ static int init_tti(struct s2io_nic *nic, int link) ...@@ -1166,7 +1166,7 @@ static int init_tti(struct s2io_nic *nic, int link)
if (wait_for_cmd_complete(&bar0->tti_command_mem, if (wait_for_cmd_complete(&bar0->tti_command_mem,
TTI_CMD_MEM_STROBE_NEW_CMD, TTI_CMD_MEM_STROBE_NEW_CMD,
S2IO_BIT_RESET) != SUCCESS) S2IO_BIT_RESET, may_sleep) != SUCCESS)
return FAILURE; return FAILURE;
} }
...@@ -1659,7 +1659,7 @@ static int init_nic(struct s2io_nic *nic) ...@@ -1659,7 +1659,7 @@ static int init_nic(struct s2io_nic *nic)
*/ */
/* Initialize TTI */ /* Initialize TTI */
if (SUCCESS != init_tti(nic, nic->last_link_state)) if (SUCCESS != init_tti(nic, nic->last_link_state, true))
return -ENODEV; return -ENODEV;
/* RTI Initialization */ /* RTI Initialization */
...@@ -3331,7 +3331,7 @@ static void s2io_updt_xpak_counter(struct net_device *dev) ...@@ -3331,7 +3331,7 @@ static void s2io_updt_xpak_counter(struct net_device *dev)
*/ */
static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit, static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit,
int bit_state) int bit_state, bool may_sleep)
{ {
int ret = FAILURE, cnt = 0, delay = 1; int ret = FAILURE, cnt = 0, delay = 1;
u64 val64; u64 val64;
...@@ -3353,7 +3353,7 @@ static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit, ...@@ -3353,7 +3353,7 @@ static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit,
} }
} }
if (in_interrupt()) if (!may_sleep)
mdelay(delay); mdelay(delay);
else else
msleep(delay); msleep(delay);
...@@ -4877,8 +4877,7 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev) ...@@ -4877,8 +4877,7 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev)
* Return value: * Return value:
* void. * void.
*/ */
static void s2io_set_multicast(struct net_device *dev, bool may_sleep)
static void s2io_set_multicast(struct net_device *dev)
{ {
int i, j, prev_cnt; int i, j, prev_cnt;
struct netdev_hw_addr *ha; struct netdev_hw_addr *ha;
...@@ -4903,7 +4902,7 @@ static void s2io_set_multicast(struct net_device *dev) ...@@ -4903,7 +4902,7 @@ static void s2io_set_multicast(struct net_device *dev)
/* Wait till command completes */ /* Wait till command completes */
wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
S2IO_BIT_RESET); S2IO_BIT_RESET, may_sleep);
sp->m_cast_flg = 1; sp->m_cast_flg = 1;
sp->all_multi_pos = config->max_mc_addr - 1; sp->all_multi_pos = config->max_mc_addr - 1;
...@@ -4920,7 +4919,7 @@ static void s2io_set_multicast(struct net_device *dev) ...@@ -4920,7 +4919,7 @@ static void s2io_set_multicast(struct net_device *dev)
/* Wait till command completes */ /* Wait till command completes */
wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
S2IO_BIT_RESET); S2IO_BIT_RESET, may_sleep);
sp->m_cast_flg = 0; sp->m_cast_flg = 0;
sp->all_multi_pos = 0; sp->all_multi_pos = 0;
...@@ -5000,7 +4999,7 @@ static void s2io_set_multicast(struct net_device *dev) ...@@ -5000,7 +4999,7 @@ static void s2io_set_multicast(struct net_device *dev)
/* Wait for command completes */ /* Wait for command completes */
if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
S2IO_BIT_RESET)) { S2IO_BIT_RESET, may_sleep)) {
DBG_PRINT(ERR_DBG, DBG_PRINT(ERR_DBG,
"%s: Adding Multicasts failed\n", "%s: Adding Multicasts failed\n",
dev->name); dev->name);
...@@ -5030,7 +5029,7 @@ static void s2io_set_multicast(struct net_device *dev) ...@@ -5030,7 +5029,7 @@ static void s2io_set_multicast(struct net_device *dev)
/* Wait for command completes */ /* Wait for command completes */
if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
S2IO_BIT_RESET)) { S2IO_BIT_RESET, may_sleep)) {
DBG_PRINT(ERR_DBG, DBG_PRINT(ERR_DBG,
"%s: Adding Multicasts failed\n", "%s: Adding Multicasts failed\n",
dev->name); dev->name);
...@@ -5041,6 +5040,12 @@ static void s2io_set_multicast(struct net_device *dev) ...@@ -5041,6 +5040,12 @@ static void s2io_set_multicast(struct net_device *dev)
} }
} }
/* NDO wrapper for s2io_set_multicast */
static void s2io_ndo_set_multicast(struct net_device *dev)
{
s2io_set_multicast(dev, false);
}
/* read from CAM unicast & multicast addresses and store it in /* read from CAM unicast & multicast addresses and store it in
* def_mac_addr structure * def_mac_addr structure
*/ */
...@@ -5127,7 +5132,7 @@ static int do_s2io_add_mac(struct s2io_nic *sp, u64 addr, int off) ...@@ -5127,7 +5132,7 @@ static int do_s2io_add_mac(struct s2io_nic *sp, u64 addr, int off)
/* Wait till command completes */ /* Wait till command completes */
if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
S2IO_BIT_RESET)) { S2IO_BIT_RESET, true)) {
DBG_PRINT(INFO_DBG, "do_s2io_add_mac failed\n"); DBG_PRINT(INFO_DBG, "do_s2io_add_mac failed\n");
return FAILURE; return FAILURE;
} }
...@@ -5171,7 +5176,7 @@ static u64 do_s2io_read_unicast_mc(struct s2io_nic *sp, int offset) ...@@ -5171,7 +5176,7 @@ static u64 do_s2io_read_unicast_mc(struct s2io_nic *sp, int offset)
/* Wait till command completes */ /* Wait till command completes */
if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
S2IO_BIT_RESET)) { S2IO_BIT_RESET, true)) {
DBG_PRINT(INFO_DBG, "do_s2io_read_unicast_mc failed\n"); DBG_PRINT(INFO_DBG, "do_s2io_read_unicast_mc failed\n");
return FAILURE; return FAILURE;
} }
...@@ -7141,7 +7146,7 @@ static int s2io_card_up(struct s2io_nic *sp) ...@@ -7141,7 +7146,7 @@ static int s2io_card_up(struct s2io_nic *sp)
} }
/* Setting its receive mode */ /* Setting its receive mode */
s2io_set_multicast(dev); s2io_set_multicast(dev, true);
if (dev->features & NETIF_F_LRO) { if (dev->features & NETIF_F_LRO) {
/* Initialize max aggregatable pkts per session based on MTU */ /* Initialize max aggregatable pkts per session based on MTU */
...@@ -7447,7 +7452,7 @@ static void s2io_link(struct s2io_nic *sp, int link) ...@@ -7447,7 +7452,7 @@ static void s2io_link(struct s2io_nic *sp, int link)
struct swStat *swstats = &sp->mac_control.stats_info->sw_stat; struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
if (link != sp->last_link_state) { if (link != sp->last_link_state) {
init_tti(sp, link); init_tti(sp, link, false);
if (link == LINK_DOWN) { if (link == LINK_DOWN) {
DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name); DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
s2io_stop_all_tx_queue(sp); s2io_stop_all_tx_queue(sp);
...@@ -7604,7 +7609,7 @@ static int rts_ds_steer(struct s2io_nic *nic, u8 ds_codepoint, u8 ring) ...@@ -7604,7 +7609,7 @@ static int rts_ds_steer(struct s2io_nic *nic, u8 ds_codepoint, u8 ring)
return wait_for_cmd_complete(&bar0->rts_ds_mem_ctrl, return wait_for_cmd_complete(&bar0->rts_ds_mem_ctrl,
RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED, RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED,
S2IO_BIT_RESET); S2IO_BIT_RESET, true);
} }
static const struct net_device_ops s2io_netdev_ops = { static const struct net_device_ops s2io_netdev_ops = {
...@@ -7613,7 +7618,7 @@ static const struct net_device_ops s2io_netdev_ops = { ...@@ -7613,7 +7618,7 @@ static const struct net_device_ops s2io_netdev_ops = {
.ndo_get_stats = s2io_get_stats, .ndo_get_stats = s2io_get_stats,
.ndo_start_xmit = s2io_xmit, .ndo_start_xmit = s2io_xmit,
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
.ndo_set_rx_mode = s2io_set_multicast, .ndo_set_rx_mode = s2io_ndo_set_multicast,
.ndo_do_ioctl = s2io_ioctl, .ndo_do_ioctl = s2io_ioctl,
.ndo_set_mac_address = s2io_set_mac_addr, .ndo_set_mac_address = s2io_set_mac_addr,
.ndo_change_mtu = s2io_change_mtu, .ndo_change_mtu = s2io_change_mtu,
...@@ -7929,7 +7934,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) ...@@ -7929,7 +7934,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
writeq(val64, &bar0->rmac_addr_cmd_mem); writeq(val64, &bar0->rmac_addr_cmd_mem);
wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
S2IO_BIT_RESET); S2IO_BIT_RESET, true);
tmp64 = readq(&bar0->rmac_addr_data0_mem); tmp64 = readq(&bar0->rmac_addr_data0_mem);
mac_down = (u32)tmp64; mac_down = (u32)tmp64;
mac_up = (u32) (tmp64 >> 32); mac_up = (u32) (tmp64 >> 32);
......
...@@ -1066,7 +1066,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data); ...@@ -1066,7 +1066,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data);
static void s2io_handle_errors(void * dev_id); static void s2io_handle_errors(void * dev_id);
static void s2io_tx_watchdog(struct net_device *dev, unsigned int txqueue); static void s2io_tx_watchdog(struct net_device *dev, unsigned int txqueue);
static void s2io_set_multicast(struct net_device *dev); static void s2io_set_multicast(struct net_device *dev, bool may_sleep);
static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp); static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp);
static void s2io_link(struct s2io_nic * sp, int link); static void s2io_link(struct s2io_nic * sp, int link);
static void s2io_reset(struct s2io_nic * sp); static void s2io_reset(struct s2io_nic * sp);
...@@ -1087,7 +1087,7 @@ static int s2io_set_swapper(struct s2io_nic * sp); ...@@ -1087,7 +1087,7 @@ static int s2io_set_swapper(struct s2io_nic * sp);
static void s2io_card_down(struct s2io_nic *nic); static void s2io_card_down(struct s2io_nic *nic);
static int s2io_card_up(struct s2io_nic *nic); static int s2io_card_up(struct s2io_nic *nic);
static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit, static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit,
int bit_state); int bit_state, bool may_sleep);
static int s2io_add_isr(struct s2io_nic * sp); static int s2io_add_isr(struct s2io_nic * sp);
static void s2io_rem_isr(struct s2io_nic * sp); static void s2io_rem_isr(struct s2io_nic * sp);
......
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