Skip to content

Commit

Permalink
Merge branch 'in_interrupt-cleanup-part-2'
Browse files Browse the repository at this point in the history
Sebastian Andrzej Siewior says:

====================
in_interrupt() cleanup, part 2

in the discussion about preempt count consistency across kernel configurations:

  https://lore.kernel.org/r/20200914204209.256266093@linutronix.de/

Linus clearly requested that code in drivers and libraries which changes
behaviour based on execution context should either be split up so that
e.g. task context invocations and BH invocations have different interfaces
or if that's not possible the context information has to be provided by the
caller which knows in which context it is executing.

This includes conditional locking, allocation mode (GFP_*) decisions and
avoidance of code paths which might sleep.

In the long run, usage of 'preemptible, in_*irq etc.' should be banned from
driver code completely.

This is part two addressing remaining drivers except for orinoco-usb.
====================

Cherry picking only Ethernet changes.

Link: https://lore.kernel.org/r/20201027225454.3492351-1-bigeasy@linutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Oct 31, 2020
2 parents 68bb466 + beca928 commit 4e5d79b
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 66 deletions.
41 changes: 23 additions & 18 deletions drivers/net/ethernet/neterion/s2io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1106,7 +1106,7 @@ static int s2io_print_pci_mode(struct s2io_nic *nic)
* '-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;
register u64 val64 = 0;
Expand Down Expand Up @@ -1166,7 +1166,7 @@ static int init_tti(struct s2io_nic *nic, int link)

if (wait_for_cmd_complete(&bar0->tti_command_mem,
TTI_CMD_MEM_STROBE_NEW_CMD,
S2IO_BIT_RESET) != SUCCESS)
S2IO_BIT_RESET, may_sleep) != SUCCESS)
return FAILURE;
}

Expand Down Expand Up @@ -1659,7 +1659,7 @@ static int init_nic(struct s2io_nic *nic)
*/

/* Initialize TTI */
if (SUCCESS != init_tti(nic, nic->last_link_state))
if (SUCCESS != init_tti(nic, nic->last_link_state, true))
return -ENODEV;

/* RTI Initialization */
Expand Down Expand Up @@ -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,
int bit_state)
int bit_state, bool may_sleep)
{
int ret = FAILURE, cnt = 0, delay = 1;
u64 val64;
Expand All @@ -3353,7 +3353,7 @@ static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit,
}
}

if (in_interrupt())
if (!may_sleep)
mdelay(delay);
else
msleep(delay);
Expand Down Expand Up @@ -4877,8 +4877,7 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev)
* Return value:
* void.
*/

static void s2io_set_multicast(struct net_device *dev)
static void s2io_set_multicast(struct net_device *dev, bool may_sleep)
{
int i, j, prev_cnt;
struct netdev_hw_addr *ha;
Expand All @@ -4903,7 +4902,7 @@ static void s2io_set_multicast(struct net_device *dev)
/* Wait till command completes */
wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
S2IO_BIT_RESET);
S2IO_BIT_RESET, may_sleep);

sp->m_cast_flg = 1;
sp->all_multi_pos = config->max_mc_addr - 1;
Expand All @@ -4920,7 +4919,7 @@ static void s2io_set_multicast(struct net_device *dev)
/* Wait till command completes */
wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
S2IO_BIT_RESET);
S2IO_BIT_RESET, may_sleep);

sp->m_cast_flg = 0;
sp->all_multi_pos = 0;
Expand Down Expand Up @@ -5000,7 +4999,7 @@ static void s2io_set_multicast(struct net_device *dev)
/* Wait for command completes */
if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
S2IO_BIT_RESET)) {
S2IO_BIT_RESET, may_sleep)) {
DBG_PRINT(ERR_DBG,
"%s: Adding Multicasts failed\n",
dev->name);
Expand Down Expand Up @@ -5030,7 +5029,7 @@ static void s2io_set_multicast(struct net_device *dev)
/* Wait for command completes */
if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
S2IO_BIT_RESET)) {
S2IO_BIT_RESET, may_sleep)) {
DBG_PRINT(ERR_DBG,
"%s: Adding Multicasts failed\n",
dev->name);
Expand All @@ -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
* def_mac_addr structure
*/
Expand Down Expand Up @@ -5127,7 +5132,7 @@ static int do_s2io_add_mac(struct s2io_nic *sp, u64 addr, int off)
/* Wait till command completes */
if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
S2IO_BIT_RESET)) {
S2IO_BIT_RESET, true)) {
DBG_PRINT(INFO_DBG, "do_s2io_add_mac failed\n");
return FAILURE;
}
Expand Down Expand Up @@ -5171,7 +5176,7 @@ static u64 do_s2io_read_unicast_mc(struct s2io_nic *sp, int offset)
/* Wait till command completes */
if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
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");
return FAILURE;
}
Expand Down Expand Up @@ -7141,7 +7146,7 @@ static int s2io_card_up(struct s2io_nic *sp)
}

/* Setting its receive mode */
s2io_set_multicast(dev);
s2io_set_multicast(dev, true);

if (dev->features & NETIF_F_LRO) {
/* Initialize max aggregatable pkts per session based on MTU */
Expand Down Expand Up @@ -7447,7 +7452,7 @@ static void s2io_link(struct s2io_nic *sp, int link)
struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;

if (link != sp->last_link_state) {
init_tti(sp, link);
init_tti(sp, link, false);
if (link == LINK_DOWN) {
DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
s2io_stop_all_tx_queue(sp);
Expand Down Expand Up @@ -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,
RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED,
S2IO_BIT_RESET);
S2IO_BIT_RESET, true);
}

static const struct net_device_ops s2io_netdev_ops = {
Expand All @@ -7613,7 +7618,7 @@ static const struct net_device_ops s2io_netdev_ops = {
.ndo_get_stats = s2io_get_stats,
.ndo_start_xmit = s2io_xmit,
.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_set_mac_address = s2io_set_mac_addr,
.ndo_change_mtu = s2io_change_mtu,
Expand Down Expand Up @@ -7929,7 +7934,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
writeq(val64, &bar0->rmac_addr_cmd_mem);
wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
S2IO_BIT_RESET);
S2IO_BIT_RESET, true);
tmp64 = readq(&bar0->rmac_addr_data0_mem);
mac_down = (u32)tmp64;
mac_up = (u32) (tmp64 >> 32);
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/neterion/s2io.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_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 void s2io_link(struct s2io_nic * sp, int link);
static void s2io_reset(struct s2io_nic * sp);
Expand All @@ -1087,7 +1087,7 @@ static int s2io_set_swapper(struct s2io_nic * sp);
static void s2io_card_down(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,
int bit_state);
int bit_state, bool may_sleep);
static int s2io_add_isr(struct s2io_nic * sp);
static void s2io_rem_isr(struct s2io_nic * sp);

Expand Down
6 changes: 1 addition & 5 deletions drivers/net/ethernet/nvidia/forcedeth.c
Original file line number Diff line number Diff line change
Expand Up @@ -1666,11 +1666,7 @@ static void nv_update_stats(struct net_device *dev)
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);

/* If it happens that this is run in top-half context, then
* replace the spin_lock of hwstats_lock with
* spin_lock_irqsave() in calling functions. */
WARN_ONCE(in_irq(), "forcedeth: estats spin_lock(_bh) from top-half");
assert_spin_locked(&np->hwstats_lock);
lockdep_assert_held(&np->hwstats_lock);

/* query hardware */
np->estats.tx_bytes += readl(base + NvRegTxCnt);
Expand Down
Loading

0 comments on commit 4e5d79b

Please sign in to comment.