forked from Minki/linux
staging/rdma/hfi1: Method to toggle "fast ECN" detection
Add a per port sysfs paramter to toggle cc_prescan/Fast ECN Detection and remove the Kconfig option which was previously used to control this. While am updating the sysfs documentation, fix the name of CCMgtA. Reviewed-by: Arthur Kepner <arthur.kepner@intel.com> Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Signed-off-by: Vennila Megavannan <vennila.megavannan@intel.com> Signed-off-by: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
parent
566c157cbd
commit
6c9e50f894
@ -78,9 +78,10 @@ HFI1
|
|||||||
chip_reset - diagnostic (root only)
|
chip_reset - diagnostic (root only)
|
||||||
boardversion - board version
|
boardversion - board version
|
||||||
ports/1/
|
ports/1/
|
||||||
CMgtA/
|
CCMgtA/
|
||||||
cc_settings_bin - CCA tables used by PSM2
|
cc_settings_bin - CCA tables used by PSM2
|
||||||
cc_table_bin
|
cc_table_bin
|
||||||
|
cc_prescan - enable prescaning for faster BECN response
|
||||||
sc2v/ - 32 files (0 - 31) used to translate sl->vl
|
sc2v/ - 32 files (0 - 31) used to translate sl->vl
|
||||||
sl2sc/ - 32 files (0 - 31) used to translate sl->sc
|
sl2sc/ - 32 files (0 - 31) used to translate sl->sc
|
||||||
vl2mtu/ - 16 (0 - 15) files used to determine MTU for vl
|
vl2mtu/ - 16 (0 - 15) files used to determine MTU for vl
|
||||||
|
@ -26,13 +26,3 @@ config SDMA_VERBOSITY
|
|||||||
---help---
|
---help---
|
||||||
This is a configuration flag to enable verbose
|
This is a configuration flag to enable verbose
|
||||||
SDMA debug
|
SDMA debug
|
||||||
config PRESCAN_RXQ
|
|
||||||
bool "Enable prescanning of the RX queue for ECNs"
|
|
||||||
depends on INFINIBAND_HFI1
|
|
||||||
default n
|
|
||||||
---help---
|
|
||||||
This option toggles the prescanning of the receive queue for
|
|
||||||
Explicit Congestion Notifications. If an ECN is detected, it
|
|
||||||
is processed as quickly as possible, the ECN is toggled off.
|
|
||||||
After the prescanning step, the receive queue is processed as
|
|
||||||
usual.
|
|
||||||
|
@ -453,11 +453,6 @@ static inline void init_packet(struct hfi1_ctxtdata *rcd,
|
|||||||
packet->rcv_flags = 0;
|
packet->rcv_flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_PRESCAN_RXQ
|
|
||||||
static void prescan_rxq(struct hfi1_packet *packet) {}
|
|
||||||
#else /* !CONFIG_PRESCAN_RXQ */
|
|
||||||
static int prescan_receive_queue;
|
|
||||||
|
|
||||||
static void process_ecn(struct rvt_qp *qp, struct hfi1_ib_header *hdr,
|
static void process_ecn(struct rvt_qp *qp, struct hfi1_ib_header *hdr,
|
||||||
struct hfi1_other_headers *ohdr,
|
struct hfi1_other_headers *ohdr,
|
||||||
u64 rhf, u32 bth1, struct ib_grh *grh)
|
u64 rhf, u32 bth1, struct ib_grh *grh)
|
||||||
@ -581,15 +576,19 @@ static inline void update_ps_mdata(struct ps_mdata *mdata,
|
|||||||
* containing Excplicit Congestion Notifications (FECNs, or BECNs).
|
* containing Excplicit Congestion Notifications (FECNs, or BECNs).
|
||||||
* When an ECN is found, process the Congestion Notification, and toggle
|
* When an ECN is found, process the Congestion Notification, and toggle
|
||||||
* it off.
|
* it off.
|
||||||
|
* This is declared as a macro to allow quick checking of the port to avoid
|
||||||
|
* the overhead of a function call if not enabled.
|
||||||
*/
|
*/
|
||||||
static void prescan_rxq(struct hfi1_packet *packet)
|
#define prescan_rxq(rcd, packet) \
|
||||||
|
do { \
|
||||||
|
if (rcd->ppd->cc_prescan) \
|
||||||
|
__prescan_rxq(packet); \
|
||||||
|
} while (0)
|
||||||
|
static void __prescan_rxq(struct hfi1_packet *packet)
|
||||||
{
|
{
|
||||||
struct hfi1_ctxtdata *rcd = packet->rcd;
|
struct hfi1_ctxtdata *rcd = packet->rcd;
|
||||||
struct ps_mdata mdata;
|
struct ps_mdata mdata;
|
||||||
|
|
||||||
if (!prescan_receive_queue)
|
|
||||||
return;
|
|
||||||
|
|
||||||
init_ps_mdata(&mdata, packet);
|
init_ps_mdata(&mdata, packet);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -653,7 +652,6 @@ next:
|
|||||||
update_ps_mdata(&mdata, rcd);
|
update_ps_mdata(&mdata, rcd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PRESCAN_RXQ */
|
|
||||||
|
|
||||||
static inline int skip_rcv_packet(struct hfi1_packet *packet, int thread)
|
static inline int skip_rcv_packet(struct hfi1_packet *packet, int thread)
|
||||||
{
|
{
|
||||||
@ -819,7 +817,7 @@ int handle_receive_interrupt_nodma_rtail(struct hfi1_ctxtdata *rcd, int thread)
|
|||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
prescan_rxq(&packet);
|
prescan_rxq(rcd, &packet);
|
||||||
|
|
||||||
while (last == RCV_PKT_OK) {
|
while (last == RCV_PKT_OK) {
|
||||||
last = process_rcv_packet(&packet, thread);
|
last = process_rcv_packet(&packet, thread);
|
||||||
@ -850,7 +848,7 @@ int handle_receive_interrupt_dma_rtail(struct hfi1_ctxtdata *rcd, int thread)
|
|||||||
}
|
}
|
||||||
smp_rmb(); /* prevent speculative reads of dma'ed hdrq */
|
smp_rmb(); /* prevent speculative reads of dma'ed hdrq */
|
||||||
|
|
||||||
prescan_rxq(&packet);
|
prescan_rxq(rcd, &packet);
|
||||||
|
|
||||||
while (last == RCV_PKT_OK) {
|
while (last == RCV_PKT_OK) {
|
||||||
last = process_rcv_packet(&packet, thread);
|
last = process_rcv_packet(&packet, thread);
|
||||||
@ -961,7 +959,7 @@ int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prescan_rxq(&packet);
|
prescan_rxq(rcd, &packet);
|
||||||
|
|
||||||
while (last == RCV_PKT_OK) {
|
while (last == RCV_PKT_OK) {
|
||||||
|
|
||||||
|
@ -734,6 +734,8 @@ struct hfi1_pportdata {
|
|||||||
/* Error events that will cause a port bounce. */
|
/* Error events that will cause a port bounce. */
|
||||||
u32 port_error_action;
|
u32 port_error_action;
|
||||||
struct work_struct linkstate_active_work;
|
struct work_struct linkstate_active_work;
|
||||||
|
/* Does this port need to prescan for FECNs */
|
||||||
|
bool cc_prescan;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*rhf_rcv_function_ptr)(struct hfi1_packet *packet);
|
typedef int (*rhf_rcv_function_ptr)(struct hfi1_packet *packet);
|
||||||
|
@ -99,10 +99,6 @@ static void port_release(struct kobject *kobj)
|
|||||||
/* nothing to do since memory is freed by hfi1_free_devdata() */
|
/* nothing to do since memory is freed by hfi1_free_devdata() */
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct kobj_type port_cc_ktype = {
|
|
||||||
.release = port_release,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct bin_attribute cc_table_bin_attr = {
|
static struct bin_attribute cc_table_bin_attr = {
|
||||||
.attr = {.name = "cc_table_bin", .mode = 0444},
|
.attr = {.name = "cc_table_bin", .mode = 0444},
|
||||||
.read = read_cc_table_bin,
|
.read = read_cc_table_bin,
|
||||||
@ -151,6 +147,68 @@ static struct bin_attribute cc_setting_bin_attr = {
|
|||||||
.size = PAGE_SIZE,
|
.size = PAGE_SIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct hfi1_port_attr {
|
||||||
|
struct attribute attr;
|
||||||
|
ssize_t (*show)(struct hfi1_pportdata *, char *);
|
||||||
|
ssize_t (*store)(struct hfi1_pportdata *, const char *, size_t);
|
||||||
|
};
|
||||||
|
|
||||||
|
static ssize_t cc_prescan_show(struct hfi1_pportdata *ppd, char *buf)
|
||||||
|
{
|
||||||
|
return sprintf(buf, "%s\n", ppd->cc_prescan ? "on" : "off");
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t cc_prescan_store(struct hfi1_pportdata *ppd, const char *buf,
|
||||||
|
size_t count)
|
||||||
|
{
|
||||||
|
if (!memcmp(buf, "on", 2))
|
||||||
|
ppd->cc_prescan = true;
|
||||||
|
else if (!memcmp(buf, "off", 3))
|
||||||
|
ppd->cc_prescan = false;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct hfi1_port_attr cc_prescan_attr =
|
||||||
|
__ATTR(cc_prescan, 0600, cc_prescan_show, cc_prescan_store);
|
||||||
|
|
||||||
|
static ssize_t cc_attr_show(struct kobject *kobj, struct attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct hfi1_port_attr *port_attr =
|
||||||
|
container_of(attr, struct hfi1_port_attr, attr);
|
||||||
|
struct hfi1_pportdata *ppd =
|
||||||
|
container_of(kobj, struct hfi1_pportdata, pport_cc_kobj);
|
||||||
|
|
||||||
|
return port_attr->show(ppd, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t cc_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct hfi1_port_attr *port_attr =
|
||||||
|
container_of(attr, struct hfi1_port_attr, attr);
|
||||||
|
struct hfi1_pportdata *ppd =
|
||||||
|
container_of(kobj, struct hfi1_pportdata, pport_cc_kobj);
|
||||||
|
|
||||||
|
return port_attr->store(ppd, buf, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct sysfs_ops port_cc_sysfs_ops = {
|
||||||
|
.show = cc_attr_show,
|
||||||
|
.store = cc_attr_store
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct attribute *port_cc_default_attributes[] = {
|
||||||
|
&cc_prescan_attr.attr
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct kobj_type port_cc_ktype = {
|
||||||
|
.release = port_release,
|
||||||
|
.sysfs_ops = &port_cc_sysfs_ops,
|
||||||
|
.default_attrs = port_cc_default_attributes
|
||||||
|
};
|
||||||
|
|
||||||
/* Start sc2vl */
|
/* Start sc2vl */
|
||||||
#define HFI1_SC2VL_ATTR(N) \
|
#define HFI1_SC2VL_ATTR(N) \
|
||||||
static struct hfi1_sc2vl_attr hfi1_sc2vl_attr_##N = { \
|
static struct hfi1_sc2vl_attr hfi1_sc2vl_attr_##N = { \
|
||||||
|
Loading…
Reference in New Issue
Block a user