Skip to content

Commit

Permalink
scsi: hisi_sas: Pass gfp_t flags to libsas event notifiers
Browse files Browse the repository at this point in the history
Use the new libsas event notifiers API, which requires callers to
explicitly pass the gfp_t memory allocation flags.

Below are the context analysis for modified functions:

=> hisi_sas_bytes_dmaed():

Since it is invoked from both process and atomic contexts, let its callers
pass the gfp_t flags:

  * hisi_sas_main.c:
  ------------------

    hisi_sas_phyup_work(): workqueue context
      -> hisi_sas_bytes_dmaed(..., GFP_KERNEL)

    hisi_sas_controller_reset_done(): has an msleep()
      -> hisi_sas_rescan_topology()
        -> hisi_sas_phy_down()
          -> hisi_sas_bytes_dmaed(..., GFP_KERNEL)

    hisi_sas_debug_I_T_nexus_reset(): calls wait_for_completion_timeout()
      -> hisi_sas_phy_down()
        -> hisi_sas_bytes_dmaed(..., GFP_KERNEL)

  * hisi_sas_v1_hw.c:
  -------------------

    int_abnormal_v1_hw(): irq handler
      -> hisi_sas_phy_down()
        -> hisi_sas_bytes_dmaed(..., GFP_ATOMIC)

  * hisi_sas_v[23]_hw.c:
  ----------------------

    int_phy_updown_v[23]_hw(): irq handler
      -> phy_down_v[23]_hw()
        -> hisi_sas_phy_down()
          -> hisi_sas_bytes_dmaed(..., GFP_ATOMIC)

=> int_bcast_v1_hw() and phy_bcast_v3_hw():

Both are invoked exclusively from irq handlers. Pass GFP_ATOMIC.

Link: https://lore.kernel.org/r/[email protected]
Reviewed-by: John Garry <[email protected]>
Signed-off-by: Ahmed S. Darwish <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
  • Loading branch information
a-darwish authored and martinkpetersen committed Jan 23, 2021
1 parent 111d06a commit 26c7efc
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 18 deletions.
3 changes: 2 additions & 1 deletion drivers/scsi/hisi_sas/hisi_sas.h
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,8 @@ extern void hisi_sas_scan_start(struct Scsi_Host *shost);
extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type);
extern void hisi_sas_phy_enable(struct hisi_hba *hisi_hba, int phy_no,
int enable);
extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy);
extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy,
gfp_t gfp_flags);
extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba,
struct sas_task *task,
struct hisi_sas_slot *slot);
Expand Down
26 changes: 15 additions & 11 deletions drivers/scsi/hisi_sas/hisi_sas_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,8 @@ static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags,
return rc;
}

static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no)
static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no,
gfp_t gfp_flags)
{
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
struct asd_sas_phy *sas_phy = &phy->sas_phy;
Expand All @@ -626,7 +627,7 @@ static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no)
return;
}

sas_notify_phy_event(sas_phy, PHYE_OOB_DONE);
sas_notify_phy_event_gfp(sas_phy, PHYE_OOB_DONE, gfp_flags);

if (sas_phy->phy) {
struct sas_phy *sphy = sas_phy->phy;
Expand Down Expand Up @@ -654,7 +655,7 @@ static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no)
}

sas_phy->frame_rcvd_size = phy->frame_rcvd_size;
sas_notify_port_event(sas_phy, PORTE_BYTES_DMAED);
sas_notify_port_event_gfp(sas_phy, PORTE_BYTES_DMAED, gfp_flags);
}

static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device)
Expand Down Expand Up @@ -860,7 +861,7 @@ static void hisi_sas_phyup_work(struct work_struct *work)

if (phy->identify.target_port_protocols == SAS_PROTOCOL_SSP)
hisi_hba->hw->sl_notify_ssp(hisi_hba, phy_no);
hisi_sas_bytes_dmaed(hisi_hba, phy_no);
hisi_sas_bytes_dmaed(hisi_hba, phy_no, GFP_KERNEL);
}

static void hisi_sas_linkreset_work(struct work_struct *work)
Expand Down Expand Up @@ -1429,11 +1430,12 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
_sas_port = sas_port;

if (dev_is_expander(dev->dev_type))
sas_notify_port_event(sas_phy,
PORTE_BROADCAST_RCVD);
sas_notify_port_event_gfp(sas_phy,
PORTE_BROADCAST_RCVD,
GFP_KERNEL);
}
} else {
hisi_sas_phy_down(hisi_hba, phy_no, 0);
hisi_sas_phy_down(hisi_hba, phy_no, 0, GFP_KERNEL);
}
}
}
Expand Down Expand Up @@ -1787,7 +1789,7 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)

/* report PHY down if timed out */
if (!ret)
hisi_sas_phy_down(hisi_hba, sas_phy->id, 0);
hisi_sas_phy_down(hisi_hba, sas_phy->id, 0, GFP_KERNEL);
} else if (sas_dev->dev_status != HISI_SAS_DEV_INIT) {
/*
* If in init state, we rely on caller to wait for link to be
Expand Down Expand Up @@ -2187,15 +2189,16 @@ static void hisi_sas_phy_disconnected(struct hisi_sas_phy *phy)
spin_unlock_irqrestore(&phy->lock, flags);
}

void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy)
void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy,
gfp_t gfp_flags)
{
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
struct asd_sas_phy *sas_phy = &phy->sas_phy;
struct device *dev = hisi_hba->dev;

if (rdy) {
/* Phy down but ready */
hisi_sas_bytes_dmaed(hisi_hba, phy_no);
hisi_sas_bytes_dmaed(hisi_hba, phy_no, gfp_flags);
hisi_sas_port_notify_formed(sas_phy);
} else {
struct hisi_sas_port *port = phy->port;
Expand All @@ -2206,7 +2209,8 @@ void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy)
return;
}
/* Phy down and not ready */
sas_notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL);
sas_notify_phy_event_gfp(sas_phy,
PHYE_LOSS_OF_SIGNAL, gfp_flags);
sas_phy_disconnected(sas_phy);

if (port) {
Expand Down
6 changes: 4 additions & 2 deletions drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1423,7 +1423,8 @@ static irqreturn_t int_bcast_v1_hw(int irq, void *p)
}

if (!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))
sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
sas_notify_port_event_gfp(sas_phy, PORTE_BROADCAST_RCVD,
GFP_ATOMIC);

end:
hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2,
Expand Down Expand Up @@ -1452,7 +1453,8 @@ static irqreturn_t int_abnormal_v1_hw(int irq, void *p)
u32 phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);

hisi_sas_phy_down(hisi_hba, phy_no,
(phy_state & 1 << phy_no) ? 1 : 0);
(phy_state & 1 << phy_no) ? 1 : 0,
GFP_ATOMIC);
}

if (irq_value & CHL_INT0_ID_TIMEOUT_MSK)
Expand Down
6 changes: 4 additions & 2 deletions drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -2734,7 +2734,8 @@ static int phy_down_v2_hw(int phy_no, struct hisi_hba *hisi_hba)

phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);
dev_info(dev, "phydown: phy%d phy_state=0x%x\n", phy_no, phy_state);
hisi_sas_phy_down(hisi_hba, phy_no, (phy_state & 1 << phy_no) ? 1 : 0);
hisi_sas_phy_down(hisi_hba, phy_no, (phy_state & 1 << phy_no) ? 1 : 0,
GFP_ATOMIC);

sl_ctrl = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL);
hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL,
Expand Down Expand Up @@ -2824,7 +2825,8 @@ static void phy_bcast_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS);
if ((bcast_status & RX_BCAST_CHG_MSK) &&
!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))
sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
sas_notify_port_event_gfp(sas_phy, PORTE_BROADCAST_RCVD,
GFP_ATOMIC);
hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
CHL_INT0_SL_RX_BCST_ACK_MSK);
hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0);
Expand Down
6 changes: 4 additions & 2 deletions drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1575,7 +1575,8 @@ static irqreturn_t phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba)

phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);
dev_info(dev, "phydown: phy%d phy_state=0x%x\n", phy_no, phy_state);
hisi_sas_phy_down(hisi_hba, phy_no, (phy_state & 1 << phy_no) ? 1 : 0);
hisi_sas_phy_down(hisi_hba, phy_no, (phy_state & 1 << phy_no) ? 1 : 0,
GFP_ATOMIC);

sl_ctrl = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL);
hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL,
Expand All @@ -1601,7 +1602,8 @@ static irqreturn_t phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS);
if ((bcast_status & RX_BCAST_CHG_MSK) &&
!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))
sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
sas_notify_port_event_gfp(sas_phy, PORTE_BROADCAST_RCVD,
GFP_ATOMIC);
hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
CHL_INT0_SL_RX_BCST_ACK_MSK);
hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0);
Expand Down

0 comments on commit 26c7efc

Please sign in to comment.