Commit 6eb4eb10 authored by Michael J. Ruhl's avatar Michael J. Ruhl Committed by Doug Ledford

IB/hfi1: Make the MSIx resource allocation a bit more flexible

The current method of allocating MSIx resources is a bit cumbersome,
and not very easily added to.

Refactor and re-order the code paths into a more consistent interface.

Update the interface so that allocations are not order dependent.
Reviewed-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Reviewed-by: default avatarSadanand Warrier <sadanand.warrier@intel.com>
Signed-off-by: default avatarMichael J. Ruhl <michael.j.ruhl@intel.com>
Signed-off-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 09e71899
...@@ -817,10 +817,10 @@ static void hfi1_update_sdma_affinity(struct hfi1_msix_entry *msix, int cpu) ...@@ -817,10 +817,10 @@ static void hfi1_update_sdma_affinity(struct hfi1_msix_entry *msix, int cpu)
set = &entry->def_intr; set = &entry->def_intr;
cpumask_set_cpu(cpu, &set->mask); cpumask_set_cpu(cpu, &set->mask);
cpumask_set_cpu(cpu, &set->used); cpumask_set_cpu(cpu, &set->used);
for (i = 0; i < dd->num_msix_entries; i++) { for (i = 0; i < dd->msix_info.max_requested; i++) {
struct hfi1_msix_entry *other_msix; struct hfi1_msix_entry *other_msix;
other_msix = &dd->msix_entries[i]; other_msix = &dd->msix_info.msix_entries[i];
if (other_msix->type != IRQ_SDMA || other_msix == msix) if (other_msix->type != IRQ_SDMA || other_msix == msix)
continue; continue;
......
...@@ -13099,6 +13099,35 @@ void reset_interrupts(struct hfi1_devdata *dd) ...@@ -13099,6 +13099,35 @@ void reset_interrupts(struct hfi1_devdata *dd)
write_csr(dd, CCE_INT_MAP + (8 * i), 0); write_csr(dd, CCE_INT_MAP + (8 * i), 0);
} }
/**
* set_up_interrupts() - Initialize the IRQ resources and state
* @dd: valid devdata
*
*/
static int set_up_interrupts(struct hfi1_devdata *dd)
{
int ret;
/* mask all interrupts */
set_intr_state(dd, 0);
/* clear all pending interrupts */
clear_all_interrupts(dd);
/* reset general handler mask, chip MSI-X mappings */
reset_interrupts(dd);
/* ask for MSI-X interrupts */
ret = msix_initialize(dd);
if (ret)
return ret;
ret = msix_request_irqs(dd);
if (ret)
msix_clean_up_interrupts(dd);
return ret;
}
/* /*
* Set up context values in dd. Sets: * Set up context values in dd. Sets:
* *
...@@ -14966,7 +14995,7 @@ int hfi1_init_dd(struct hfi1_devdata *dd) ...@@ -14966,7 +14995,7 @@ int hfi1_init_dd(struct hfi1_devdata *dd)
free_cntrs(dd); free_cntrs(dd);
bail_clear_intr: bail_clear_intr:
hfi1_comp_vectors_clean_up(dd); hfi1_comp_vectors_clean_up(dd);
hfi1_clean_up_interrupts(dd); msix_clean_up_interrupts(dd);
bail_cleanup: bail_cleanup:
hfi1_pcie_ddcleanup(dd); hfi1_pcie_ddcleanup(dd);
bail_free: bail_free:
......
...@@ -668,6 +668,14 @@ struct hfi1_msix_entry { ...@@ -668,6 +668,14 @@ struct hfi1_msix_entry {
struct irq_affinity_notify notify; struct irq_affinity_notify notify;
}; };
struct hfi1_msix_info {
/* lock to synchronize in_use_msix access */
spinlock_t msix_lock;
DECLARE_BITMAP(in_use_msix, CCE_NUM_MSIX_VECTORS);
struct hfi1_msix_entry *msix_entries;
u16 max_requested;
};
/* per-SL CCA information */ /* per-SL CCA information */
struct cca_timer { struct cca_timer {
struct hrtimer hrtimer; struct hrtimer hrtimer;
...@@ -993,7 +1001,6 @@ struct hfi1_vnic_data { ...@@ -993,7 +1001,6 @@ struct hfi1_vnic_data {
struct idr vesw_idr; struct idr vesw_idr;
u8 rmt_start; u8 rmt_start;
u8 num_ctxt; u8 num_ctxt;
u32 msix_idx;
}; };
struct hfi1_vnic_vport_info; struct hfi1_vnic_vport_info;
...@@ -1207,9 +1214,7 @@ struct hfi1_devdata { ...@@ -1207,9 +1214,7 @@ struct hfi1_devdata {
struct diag_client *diag_client; struct diag_client *diag_client;
/* MSI-X information */ /* MSI-X information */
struct hfi1_msix_entry *msix_entries; struct hfi1_msix_info msix_info;
u32 num_msix_entries;
u32 first_dyn_msix_idx;
/* general interrupt: mask of handled interrupts */ /* general interrupt: mask of handled interrupts */
u64 gi_mask[CCE_NUM_INT_CSRS]; u64 gi_mask[CCE_NUM_INT_CSRS];
......
...@@ -1052,7 +1052,7 @@ static void shutdown_device(struct hfi1_devdata *dd) ...@@ -1052,7 +1052,7 @@ static void shutdown_device(struct hfi1_devdata *dd)
/* mask and clean up interrupts, but not errors */ /* mask and clean up interrupts, but not errors */
set_intr_state(dd, 0); set_intr_state(dd, 0);
hfi1_clean_up_interrupts(dd); msix_clean_up_interrupts(dd);
for (pidx = 0; pidx < dd->num_pports; ++pidx) { for (pidx = 0; pidx < dd->num_pports; ++pidx) {
ppd = dd->pport + pidx; ppd = dd->pport + pidx;
...@@ -1738,7 +1738,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1738,7 +1738,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dd_dev_err(dd, "Failed to create /dev devices: %d\n", -j); dd_dev_err(dd, "Failed to create /dev devices: %d\n", -j);
if (initfail || ret) { if (initfail || ret) {
hfi1_clean_up_interrupts(dd); msix_clean_up_interrupts(dd);
stop_timers(dd); stop_timers(dd);
flush_workqueue(ib_wq); flush_workqueue(ib_wq);
for (pidx = 0; pidx < dd->num_pports; ++pidx) { for (pidx = 0; pidx < dd->num_pports; ++pidx) {
......
This diff is collapsed.
...@@ -51,14 +51,14 @@ ...@@ -51,14 +51,14 @@
#include "hfi.h" #include "hfi.h"
/* MSIx interface */ /* MSIx interface */
int request_msix(struct hfi1_devdata *dd, u32 msireq); int msix_initialize(struct hfi1_devdata *dd);
int set_up_interrupts(struct hfi1_devdata *dd); int msix_request_irqs(struct hfi1_devdata *dd);
int request_msix_irqs(struct hfi1_devdata *dd); void msix_clean_up_interrupts(struct hfi1_devdata *dd);
void hfi1_clean_up_interrupts(struct hfi1_devdata *dd); int msix_request_rcd_irq(struct hfi1_ctxtdata *rcd);
int msix_request_sdma_irq(struct sdma_engine *sde);
void msix_free_irq(struct hfi1_devdata *dd, u8 msix_intr);
/* VNIC interface */ /* VNIC interface */
void hfi1_vnic_synchronize_irq(struct hfi1_devdata *dd); void msix_vnic_synchronize_irq(struct hfi1_devdata *dd);
void hfi1_set_vnic_msix_info(struct hfi1_ctxtdata *rcd);
void hfi1_reset_vnic_msix_info(struct hfi1_ctxtdata *rcd);
#endif #endif
...@@ -405,6 +405,7 @@ struct sdma_engine { ...@@ -405,6 +405,7 @@ struct sdma_engine {
struct list_head flushlist; struct list_head flushlist;
struct cpumask cpu_mask; struct cpumask cpu_mask;
struct kobject kobj; struct kobject kobj;
u32 msix_intr;
}; };
int sdma_init(struct hfi1_devdata *dd, u8 port); int sdma_init(struct hfi1_devdata *dd, u8 port);
......
...@@ -120,7 +120,7 @@ static int allocate_vnic_ctxt(struct hfi1_devdata *dd, ...@@ -120,7 +120,7 @@ static int allocate_vnic_ctxt(struct hfi1_devdata *dd,
uctxt->seq_cnt = 1; uctxt->seq_cnt = 1;
uctxt->is_vnic = true; uctxt->is_vnic = true;
hfi1_set_vnic_msix_info(uctxt); msix_request_rcd_irq(uctxt);
hfi1_stats.sps_ctxts++; hfi1_stats.sps_ctxts++;
dd_dev_dbg(dd, "created vnic context %d\n", uctxt->ctxt); dd_dev_dbg(dd, "created vnic context %d\n", uctxt->ctxt);
...@@ -135,8 +135,6 @@ static void deallocate_vnic_ctxt(struct hfi1_devdata *dd, ...@@ -135,8 +135,6 @@ static void deallocate_vnic_ctxt(struct hfi1_devdata *dd,
dd_dev_dbg(dd, "closing vnic context %d\n", uctxt->ctxt); dd_dev_dbg(dd, "closing vnic context %d\n", uctxt->ctxt);
flush_wc(); flush_wc();
hfi1_reset_vnic_msix_info(uctxt);
/* /*
* Disable receive context and interrupt available, reset all * Disable receive context and interrupt available, reset all
* RcvCtxtCtrl bits to default values. * RcvCtxtCtrl bits to default values.
...@@ -148,6 +146,10 @@ static void deallocate_vnic_ctxt(struct hfi1_devdata *dd, ...@@ -148,6 +146,10 @@ static void deallocate_vnic_ctxt(struct hfi1_devdata *dd,
HFI1_RCVCTRL_NO_RHQ_DROP_DIS | HFI1_RCVCTRL_NO_RHQ_DROP_DIS |
HFI1_RCVCTRL_NO_EGR_DROP_DIS, uctxt); HFI1_RCVCTRL_NO_EGR_DROP_DIS, uctxt);
/* msix_intr will always be > 0, only clean up if this is true */
if (uctxt->msix_intr)
msix_free_irq(dd, uctxt->msix_intr);
uctxt->event_flags = 0; uctxt->event_flags = 0;
hfi1_clear_tids(uctxt); hfi1_clear_tids(uctxt);
...@@ -626,7 +628,7 @@ static void hfi1_vnic_down(struct hfi1_vnic_vport_info *vinfo) ...@@ -626,7 +628,7 @@ static void hfi1_vnic_down(struct hfi1_vnic_vport_info *vinfo)
idr_remove(&dd->vnic.vesw_idr, vinfo->vesw_id); idr_remove(&dd->vnic.vesw_idr, vinfo->vesw_id);
/* ensure irqs see the change */ /* ensure irqs see the change */
hfi1_vnic_synchronize_irq(dd); msix_vnic_synchronize_irq(dd);
/* remove unread skbs */ /* remove unread skbs */
for (i = 0; i < vinfo->num_rx_q; i++) { for (i = 0; i < vinfo->num_rx_q; i++) {
...@@ -690,8 +692,6 @@ static int hfi1_vnic_init(struct hfi1_vnic_vport_info *vinfo) ...@@ -690,8 +692,6 @@ static int hfi1_vnic_init(struct hfi1_vnic_vport_info *vinfo)
rc = hfi1_vnic_txreq_init(dd); rc = hfi1_vnic_txreq_init(dd);
if (rc) if (rc)
goto txreq_fail; goto txreq_fail;
dd->vnic.msix_idx = dd->first_dyn_msix_idx;
} }
for (i = dd->vnic.num_ctxt; i < vinfo->num_rx_q; i++) { for (i = dd->vnic.num_ctxt; i < vinfo->num_rx_q; i++) {
......
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