Skip to content

Commit 453e809

Browse files
committed
Improve the NT partition state transition ops
When one host and its peer are trying to do NT partition state transitions for some NT partition setup operations on a single partition, they may conflict with each other and step onto each other's toes. These NT partition setup operations include requester ID setup and memory windows setup. We introduced some checks to ensure that we only do the NT partition state transitions when the peer is not doing. When seeing a conflict we will retry after a short delay.
1 parent cbaf375 commit 453e809

File tree

1 file changed

+56
-4
lines changed

1 file changed

+56
-4
lines changed

ntb_hw_switchtec.c

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@ static struct switchtec_ntb *ntb_sndev(struct ntb_dev *ntb)
134134
return container_of(ntb, struct switchtec_ntb, ntb);
135135
}
136136

137-
static int switchtec_ntb_part_op(struct switchtec_ntb *sndev,
138-
struct ntb_ctrl_regs __iomem *ctl,
139-
u32 op, int wait_status)
137+
static int switchtec_ntb_part_op_no_retry(struct switchtec_ntb *sndev,
138+
struct ntb_ctrl_regs __iomem *ctl,
139+
u32 op, int wait_status)
140140
{
141141
static const char * const op_text[] = {
142142
[NTB_CTRL_PART_OP_LOCK] = "lock",
@@ -147,6 +147,24 @@ static int switchtec_ntb_part_op(struct switchtec_ntb *sndev,
147147
int i;
148148
u32 ps;
149149
int status;
150+
int part_id, locked_part_id;
151+
int xlink_peer = ctl == sndev->mmio_xlink_peer_ctrl ? 1 : 0;
152+
153+
ps = ioread32(&ctl->partition_status);
154+
155+
locked_part_id = (ps & 0xFF0000) >> 16;
156+
part_id = (ps & 0xFF000000) >> 24;
157+
158+
ps &= 0xFFFF;
159+
160+
if (ps != NTB_CTRL_PART_STATUS_NORMAL &&
161+
ps != NTB_CTRL_PART_STATUS_LOCKED)
162+
return -EAGAIN;
163+
164+
if (ps == NTB_CTRL_PART_STATUS_LOCKED)
165+
if ((xlink_peer && (locked_part_id != part_id)) ||
166+
(!xlink_peer && (locked_part_id != sndev->self_partition)))
167+
return -EAGAIN;
150168

151169
switch (op) {
152170
case NTB_CTRL_PART_OP_LOCK:
@@ -170,12 +188,24 @@ static int switchtec_ntb_part_op(struct switchtec_ntb *sndev,
170188
return -EINTR;
171189
}
172190

173-
ps = ioread32(&ctl->partition_status) & 0xFFFF;
191+
ps = ioread32(&ctl->partition_status);
192+
193+
locked_part_id = (ps & 0xFF0000) >> 16;
194+
part_id = (ps & 0xFF000000) >> 24;
195+
196+
ps &= 0xFFFF;
174197

175198
if (ps != status)
176199
break;
177200
}
178201

202+
if (ps == NTB_CTRL_PART_STATUS_LOCKED) {
203+
if ((xlink_peer && (locked_part_id != part_id)) ||
204+
(!xlink_peer &&
205+
(locked_part_id != sndev->self_partition)))
206+
return -EAGAIN;
207+
}
208+
179209
if (ps == wait_status)
180210
return 0;
181211

@@ -191,6 +221,28 @@ static int switchtec_ntb_part_op(struct switchtec_ntb *sndev,
191221
return -EIO;
192222
}
193223

224+
static int switchtec_ntb_part_op(struct switchtec_ntb *sndev,
225+
struct ntb_ctrl_regs __iomem *ctl,
226+
u32 op, int wait_status)
227+
{
228+
int rc;
229+
int i = 0;
230+
231+
while (i++ < 10) {
232+
rc = switchtec_ntb_part_op_no_retry(sndev, ctl, op,
233+
wait_status);
234+
if (rc == -EAGAIN) {
235+
if (msleep_interruptible(30) != 0)
236+
return -EINTR;
237+
continue;
238+
}
239+
240+
break;
241+
}
242+
243+
return rc;
244+
}
245+
194246
static int switchtec_ntb_send_msg(struct switchtec_ntb *sndev, int idx,
195247
u32 val)
196248
{

0 commit comments

Comments
 (0)