Skip to content

Commit 19d8b90

Browse files
grzegorz-andrejczukjgunthorpe
authored andcommitted
IB/hfi1: RSM rules for AIP
This is implementation of RSM rule for AIP packets. AIP rule will use rule RSM2 and will match standard Infiniband packet containg BTH (LNH==BTH) and having Dest QPN prefixed with value 0x81. Spread between receive contexts will be done using source QPN bits. VNIC and AIP will share receive contexts, so their rules will point to the same RMT entries and their shared code is moved to separate functions. If any of the rules is active RMT mapping will be skipped for latter. Changed function hfi1_vnic_is_rsm_full to be more general and moved it from main header to chip.c. Changed the order of RSM rules because AIP rule as more specific one is needed to be placed before more general QOS rule. Rules are occupying two last RSM registers. Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Dennis Dalessandro <[email protected]> Reviewed-by: Mike Marciniszyn <[email protected]> Signed-off-by: Grzegorz Andrejczuk <[email protected]> Signed-off-by: Kaike Wan <[email protected]> Signed-off-by: Dennis Dalessandro <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 7f90a5a commit 19d8b90

File tree

4 files changed

+136
-50
lines changed

4 files changed

+136
-50
lines changed

drivers/infiniband/hw/hfi1/chip.c

Lines changed: 128 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,15 @@ struct flag_table {
124124

125125
/*
126126
* RSM instance allocation
127-
* 0 - Verbs
128-
* 1 - User Fecn Handling
129-
* 2 - Vnic
127+
* 0 - User Fecn Handling
128+
* 1 - Vnic
129+
* 2 - AIP
130+
* 3 - Verbs
130131
*/
131-
#define RSM_INS_VERBS 0
132-
#define RSM_INS_FECN 1
133-
#define RSM_INS_VNIC 2
132+
#define RSM_INS_FECN 0
133+
#define RSM_INS_VNIC 1
134+
#define RSM_INS_AIP 2
135+
#define RSM_INS_VERBS 3
134136

135137
/* Bit offset into the GUID which carries HFI id information */
136138
#define GUID_HFI_INDEX_SHIFT 39
@@ -171,6 +173,25 @@ struct flag_table {
171173
/* QPN[m+n:1] QW 1, OFFSET 1 */
172174
#define QPN_SELECT_OFFSET ((1ull << QW_SHIFT) | (1ull))
173175

176+
/* RSM fields for AIP */
177+
/* LRH.BTH above is reused for this rule */
178+
179+
/* BTH.DESTQP: QW 1, OFFSET 16 for match */
180+
#define BTH_DESTQP_QW 1ull
181+
#define BTH_DESTQP_BIT_OFFSET 16ull
182+
#define BTH_DESTQP_OFFSET(off) ((BTH_DESTQP_QW << QW_SHIFT) | (off))
183+
#define BTH_DESTQP_MATCH_OFFSET BTH_DESTQP_OFFSET(BTH_DESTQP_BIT_OFFSET)
184+
#define BTH_DESTQP_MASK 0xFFull
185+
#define BTH_DESTQP_VALUE 0x81ull
186+
187+
/* DETH.SQPN: QW 1 Offset 56 for select */
188+
/* We use 8 most significant Soure QPN bits as entropy fpr AIP */
189+
#define DETH_AIP_SQPN_QW 3ull
190+
#define DETH_AIP_SQPN_BIT_OFFSET 56ull
191+
#define DETH_AIP_SQPN_OFFSET(off) ((DETH_AIP_SQPN_QW << QW_SHIFT) | (off))
192+
#define DETH_AIP_SQPN_SELECT_OFFSET \
193+
DETH_AIP_SQPN_OFFSET(DETH_AIP_SQPN_BIT_OFFSET)
194+
174195
/* RSM fields for Vnic */
175196
/* L2_TYPE: QW 0, OFFSET 61 - for match */
176197
#define L2_TYPE_QW 0ull
@@ -14236,6 +14257,12 @@ static void complete_rsm_map_table(struct hfi1_devdata *dd,
1423614257
}
1423714258
}
1423814259

14260+
/* Is a receive side mapping rule */
14261+
static bool has_rsm_rule(struct hfi1_devdata *dd, u8 rule_index)
14262+
{
14263+
return read_csr(dd, RCV_RSM_CFG + (8 * rule_index)) != 0;
14264+
}
14265+
1423914266
/*
1424014267
* Add a receive side mapping rule.
1424114268
*/
@@ -14472,39 +14499,49 @@ static void init_fecn_handling(struct hfi1_devdata *dd,
1447214499
rmt->used += total_cnt;
1447314500
}
1447414501

14475-
/* Initialize RSM for VNIC */
14476-
void hfi1_init_vnic_rsm(struct hfi1_devdata *dd)
14502+
static inline bool hfi1_is_rmt_full(int start, int spare)
14503+
{
14504+
return (start + spare) > NUM_MAP_ENTRIES;
14505+
}
14506+
14507+
static bool hfi1_netdev_update_rmt(struct hfi1_devdata *dd)
1447714508
{
1447814509
u8 i, j;
1447914510
u8 ctx_id = 0;
1448014511
u64 reg;
1448114512
u32 regoff;
14482-
struct rsm_rule_data rrd;
14513+
int rmt_start = dd->vnic.rmt_start;
1448314514

14484-
if (hfi1_vnic_is_rsm_full(dd, NUM_VNIC_MAP_ENTRIES)) {
14485-
dd_dev_err(dd, "Vnic RSM disabled, rmt entries used = %d\n",
14486-
dd->vnic.rmt_start);
14487-
return;
14515+
/* We already have contexts mapped in RMT */
14516+
if (has_rsm_rule(dd, RSM_INS_VNIC) || has_rsm_rule(dd, RSM_INS_AIP)) {
14517+
dd_dev_info(dd, "Contexts are already mapped in RMT\n");
14518+
return true;
14519+
}
14520+
14521+
if (hfi1_is_rmt_full(rmt_start, NUM_VNIC_MAP_ENTRIES)) {
14522+
dd_dev_err(dd, "Not enought RMT entries used = %d\n",
14523+
rmt_start);
14524+
return false;
1448814525
}
1448914526

14490-
dev_dbg(&(dd)->pcidev->dev, "Vnic rsm start = %d, end %d\n",
14491-
dd->vnic.rmt_start,
14492-
dd->vnic.rmt_start + NUM_VNIC_MAP_ENTRIES);
14527+
dev_dbg(&(dd)->pcidev->dev, "RMT start = %d, end %d\n",
14528+
rmt_start,
14529+
rmt_start + NUM_VNIC_MAP_ENTRIES);
1449314530

1449414531
/* Update RSM mapping table, 32 regs, 256 entries - 1 ctx per byte */
14495-
regoff = RCV_RSM_MAP_TABLE + (dd->vnic.rmt_start / 8) * 8;
14532+
regoff = RCV_RSM_MAP_TABLE + (rmt_start / 8) * 8;
1449614533
reg = read_csr(dd, regoff);
1449714534
for (i = 0; i < NUM_VNIC_MAP_ENTRIES; i++) {
14498-
/* Update map register with vnic context */
14499-
j = (dd->vnic.rmt_start + i) % 8;
14535+
/* Update map register with netdev context */
14536+
j = (rmt_start + i) % 8;
1450014537
reg &= ~(0xffllu << (j * 8));
1450114538
reg |= (u64)dd->vnic.ctxt[ctx_id++]->ctxt << (j * 8);
14502-
/* Wrap up vnic ctx index */
14539+
/* Wrap up netdev ctx index */
1450314540
ctx_id %= dd->vnic.num_ctxt;
1450414541
/* Write back map register */
1450514542
if (j == 7 || ((i + 1) == NUM_VNIC_MAP_ENTRIES)) {
1450614543
dev_dbg(&(dd)->pcidev->dev,
14507-
"Vnic rsm map reg[%d] =0x%llx\n",
14544+
"RMT[%d] =0x%llx\n",
1450814545
regoff - RCV_RSM_MAP_TABLE, reg);
1450914546

1451014547
write_csr(dd, regoff, reg);
@@ -14514,35 +14551,83 @@ void hfi1_init_vnic_rsm(struct hfi1_devdata *dd)
1451414551
}
1451514552
}
1451614553

14517-
/* Add rule for vnic */
14518-
rrd.offset = dd->vnic.rmt_start;
14519-
rrd.pkt_type = 4;
14520-
/* Match 16B packets */
14521-
rrd.field1_off = L2_TYPE_MATCH_OFFSET;
14522-
rrd.mask1 = L2_TYPE_MASK;
14523-
rrd.value1 = L2_16B_VALUE;
14524-
/* Match ETH L4 packets */
14525-
rrd.field2_off = L4_TYPE_MATCH_OFFSET;
14526-
rrd.mask2 = L4_16B_TYPE_MASK;
14527-
rrd.value2 = L4_16B_ETH_VALUE;
14528-
/* Calc context from veswid and entropy */
14529-
rrd.index1_off = L4_16B_HDR_VESWID_OFFSET;
14530-
rrd.index1_width = ilog2(NUM_VNIC_MAP_ENTRIES);
14531-
rrd.index2_off = L2_16B_ENTROPY_OFFSET;
14532-
rrd.index2_width = ilog2(NUM_VNIC_MAP_ENTRIES);
14533-
add_rsm_rule(dd, RSM_INS_VNIC, &rrd);
14534-
14535-
/* Enable RSM if not already enabled */
14554+
return true;
14555+
}
14556+
14557+
static void hfi1_enable_rsm_rule(struct hfi1_devdata *dd,
14558+
int rule, struct rsm_rule_data *rrd)
14559+
{
14560+
if (!hfi1_netdev_update_rmt(dd)) {
14561+
dd_dev_err(dd, "Failed to update RMT for RSM%d rule\n", rule);
14562+
return;
14563+
}
14564+
14565+
add_rsm_rule(dd, rule, rrd);
1453614566
add_rcvctrl(dd, RCV_CTRL_RCV_RSM_ENABLE_SMASK);
1453714567
}
1453814568

14569+
void hfi1_init_aip_rsm(struct hfi1_devdata *dd)
14570+
{
14571+
/*
14572+
* go through with the initialisation only if this rule actually doesn't
14573+
* exist yet
14574+
*/
14575+
if (atomic_fetch_inc(&dd->ipoib_rsm_usr_num) == 0) {
14576+
struct rsm_rule_data rrd = {
14577+
.offset = dd->vnic.rmt_start,
14578+
.pkt_type = IB_PACKET_TYPE,
14579+
.field1_off = LRH_BTH_MATCH_OFFSET,
14580+
.mask1 = LRH_BTH_MASK,
14581+
.value1 = LRH_BTH_VALUE,
14582+
.field2_off = BTH_DESTQP_MATCH_OFFSET,
14583+
.mask2 = BTH_DESTQP_MASK,
14584+
.value2 = BTH_DESTQP_VALUE,
14585+
.index1_off = DETH_AIP_SQPN_SELECT_OFFSET +
14586+
ilog2(NUM_VNIC_MAP_ENTRIES),
14587+
.index1_width = ilog2(NUM_VNIC_MAP_ENTRIES),
14588+
.index2_off = DETH_AIP_SQPN_SELECT_OFFSET,
14589+
.index2_width = ilog2(NUM_VNIC_MAP_ENTRIES)
14590+
};
14591+
14592+
hfi1_enable_rsm_rule(dd, RSM_INS_AIP, &rrd);
14593+
}
14594+
}
14595+
14596+
/* Initialize RSM for VNIC */
14597+
void hfi1_init_vnic_rsm(struct hfi1_devdata *dd)
14598+
{
14599+
struct rsm_rule_data rrd = {
14600+
/* Add rule for vnic */
14601+
.offset = dd->vnic.rmt_start,
14602+
.pkt_type = 4,
14603+
/* Match 16B packets */
14604+
.field1_off = L2_TYPE_MATCH_OFFSET,
14605+
.mask1 = L2_TYPE_MASK,
14606+
.value1 = L2_16B_VALUE,
14607+
/* Match ETH L4 packets */
14608+
.field2_off = L4_TYPE_MATCH_OFFSET,
14609+
.mask2 = L4_16B_TYPE_MASK,
14610+
.value2 = L4_16B_ETH_VALUE,
14611+
/* Calc context from veswid and entropy */
14612+
.index1_off = L4_16B_HDR_VESWID_OFFSET,
14613+
.index1_width = ilog2(NUM_VNIC_MAP_ENTRIES),
14614+
.index2_off = L2_16B_ENTROPY_OFFSET,
14615+
.index2_width = ilog2(NUM_VNIC_MAP_ENTRIES)
14616+
};
14617+
14618+
hfi1_enable_rsm_rule(dd, RSM_INS_VNIC, &rrd);
14619+
}
14620+
1453914621
void hfi1_deinit_vnic_rsm(struct hfi1_devdata *dd)
1454014622
{
1454114623
clear_rsm_rule(dd, RSM_INS_VNIC);
14624+
}
1454214625

14543-
/* Disable RSM if used only by vnic */
14544-
if (dd->vnic.rmt_start == 0)
14545-
clear_rcvctrl(dd, RCV_CTRL_RCV_RSM_ENABLE_SMASK);
14626+
void hfi1_deinit_aip_rsm(struct hfi1_devdata *dd)
14627+
{
14628+
/* only actually clear the rule if it's the last user asking to do so */
14629+
if (atomic_fetch_add_unless(&dd->ipoib_rsm_usr_num, -1, 0) == 1)
14630+
clear_rsm_rule(dd, RSM_INS_AIP);
1454614631
}
1454714632

1454814633
static int init_rxe(struct hfi1_devdata *dd)

drivers/infiniband/hw/hfi1/chip.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef _CHIP_H
22
#define _CHIP_H
33
/*
4-
* Copyright(c) 2015 - 2018 Intel Corporation.
4+
* Copyright(c) 2015 - 2020 Intel Corporation.
55
*
66
* This file is provided under a dual BSD/GPLv2 license. When using or
77
* redistributing this file, you may do so under either license.
@@ -1455,6 +1455,8 @@ void remap_intr(struct hfi1_devdata *dd, int isrc, int msix_intr);
14551455
void remap_sdma_interrupts(struct hfi1_devdata *dd, int engine, int msix_intr);
14561456
void reset_interrupts(struct hfi1_devdata *dd);
14571457
u8 hfi1_get_qp_map(struct hfi1_devdata *dd, u8 idx);
1458+
void hfi1_init_aip_rsm(struct hfi1_devdata *dd);
1459+
void hfi1_deinit_aip_rsm(struct hfi1_devdata *dd);
14581460

14591461
/*
14601462
* Interrupt source table.

drivers/infiniband/hw/hfi1/hfi.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,12 +1417,10 @@ struct hfi1_devdata {
14171417
struct hfi1_vnic_data vnic;
14181418
/* Lock to protect IRQ SRC register access */
14191419
spinlock_t irq_src_lock;
1420-
};
14211420

1422-
static inline bool hfi1_vnic_is_rsm_full(struct hfi1_devdata *dd, int spare)
1423-
{
1424-
return (dd->vnic.rmt_start + spare) > NUM_MAP_ENTRIES;
1425-
}
1421+
/* Keeps track of IPoIB RSM rule users */
1422+
atomic_t ipoib_rsm_usr_num;
1423+
};
14261424

14271425
/* 8051 firmware version helper */
14281426
#define dc8051_ver(a, b, c) ((a) << 16 | (b) << 8 | (c))

drivers/infiniband/hw/hfi1/init.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright(c) 2015 - 2018 Intel Corporation.
2+
* Copyright(c) 2015 - 2020 Intel Corporation.
33
*
44
* This file is provided under a dual BSD/GPLv2 license. When using or
55
* redistributing this file, you may do so under either license.
@@ -1316,6 +1316,7 @@ static struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev,
13161316
goto bail;
13171317
}
13181318

1319+
atomic_set(&dd->ipoib_rsm_usr_num, 0);
13191320
return dd;
13201321

13211322
bail:

0 commit comments

Comments
 (0)