Skip to content

Commit

Permalink
Merge branch 'ice-avoid-sleeping-scheduling-in-atomic-contexts'
Browse files Browse the repository at this point in the history
Alexander Lobakin says:

====================
ice: avoid sleeping/scheduling in atomic contexts

The `ice_misc_intr() + ice_send_event_to_aux()` infamous pair failed
once again.
Fix yet another (hopefully last one) 'scheduling while atomic' splat
and finally plug the hole to gracefully return prematurely when
invoked in wrong context instead of panicking.
====================

Link: https://lore.kernel.org/r/20220323124353.2762181-1-alexandr.lobakin@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
kuba-moo committed Mar 23, 2022
2 parents 6a7d8cf + 5a31569 commit f92fcb5
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 10 deletions.
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/ice/ice.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ enum ice_pf_state {
ICE_LINK_DEFAULT_OVERRIDE_PENDING,
ICE_PHY_INIT_COMPLETE,
ICE_FD_VF_FLUSH_CTX, /* set at FD Rx IRQ or timeout */
ICE_AUX_ERR_PENDING,
ICE_STATE_NBITS /* must be last */
};

Expand Down Expand Up @@ -559,6 +560,7 @@ struct ice_pf {
wait_queue_head_t reset_wait_queue;

u32 hw_csum_rx_error;
u32 oicr_err_reg;
u16 oicr_idx; /* Other interrupt cause MSIX vector index */
u16 num_avail_sw_msix; /* remaining MSIX SW vectors left unclaimed */
u16 max_pf_txqs; /* Total Tx queues PF wide */
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_idc.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ void ice_send_event_to_aux(struct ice_pf *pf, struct iidc_event *event)
{
struct iidc_auxiliary_drv *iadrv;

if (WARN_ON_ONCE(!in_task()))
return;

if (!pf->adev)
return;

Expand Down
25 changes: 15 additions & 10 deletions drivers/net/ethernet/intel/ice/ice_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2255,6 +2255,19 @@ static void ice_service_task(struct work_struct *work)
return;
}

if (test_and_clear_bit(ICE_AUX_ERR_PENDING, pf->state)) {
struct iidc_event *event;

event = kzalloc(sizeof(*event), GFP_KERNEL);
if (event) {
set_bit(IIDC_EVENT_CRIT_ERR, event->type);
/* report the entire OICR value to AUX driver */
swap(event->reg, pf->oicr_err_reg);
ice_send_event_to_aux(pf, event);
kfree(event);
}
}

if (test_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags)) {
/* Plug aux device per request */
ice_plug_aux_dev(pf);
Expand Down Expand Up @@ -3041,17 +3054,9 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)

#define ICE_AUX_CRIT_ERR (PFINT_OICR_PE_CRITERR_M | PFINT_OICR_HMC_ERR_M | PFINT_OICR_PE_PUSH_M)
if (oicr & ICE_AUX_CRIT_ERR) {
struct iidc_event *event;

pf->oicr_err_reg |= oicr;
set_bit(ICE_AUX_ERR_PENDING, pf->state);
ena_mask &= ~ICE_AUX_CRIT_ERR;
event = kzalloc(sizeof(*event), GFP_ATOMIC);
if (event) {
set_bit(IIDC_EVENT_CRIT_ERR, event->type);
/* report the entire OICR value to AUX driver */
event->reg = oicr;
ice_send_event_to_aux(pf, event);
kfree(event);
}
}

/* Report any remaining unexpected interrupts */
Expand Down

0 comments on commit f92fcb5

Please sign in to comment.