Skip to content

Commit c5a7591

Browse files
Arvid Brodindavem330
Arvid Brodin
authored andcommitted
net/hsr: Use list_head (and rcu) instead of array for slave devices.
Signed-off-by: Arvid Brodin <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 51f3c60 commit c5a7591

9 files changed

+438
-405
lines changed

net/hsr/hsr_device.c

+134-108
Large diffs are not rendered by default.

net/hsr/hsr_framereg.c

+64-78
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,11 @@ struct hsr_node {
2727
struct list_head mac_list;
2828
unsigned char MacAddressA[ETH_ALEN];
2929
unsigned char MacAddressB[ETH_ALEN];
30-
enum hsr_dev_idx AddrB_if;/* The local slave through which AddrB
31-
* frames are received from this node
32-
*/
33-
unsigned long time_in[HSR_MAX_SLAVE];
34-
bool time_in_stale[HSR_MAX_SLAVE];
35-
u16 seq_out[HSR_MAX_DEV];
30+
/* Local slave through which AddrB frames are received from this node */
31+
enum hsr_port_type AddrB_port;
32+
unsigned long time_in[HSR_PT_PORTS];
33+
bool time_in_stale[HSR_PT_PORTS];
34+
u16 seq_out[HSR_PT_PORTS];
3635
struct rcu_head rcu_head;
3736
};
3837

@@ -154,18 +153,18 @@ int hsr_create_self_node(struct list_head *self_node_db,
154153
* We also need to detect if the sender's SlaveA and SlaveB cables have been
155154
* swapped.
156155
*/
157-
struct hsr_node *hsr_merge_node(struct hsr_priv *hsr,
158-
struct hsr_node *node,
159-
struct sk_buff *skb,
160-
enum hsr_dev_idx dev_idx)
156+
struct hsr_node *hsr_merge_node(struct hsr_node *node, struct sk_buff *skb,
157+
struct hsr_port *port)
161158
{
159+
struct hsr_priv *hsr;
162160
struct hsr_sup_payload *hsr_sp;
163161
struct hsr_ethhdr_sp *hsr_ethsup;
164162
int i;
165163
unsigned long now;
166164

167165
hsr_ethsup = (struct hsr_ethhdr_sp *) skb_mac_header(skb);
168166
hsr_sp = (struct hsr_sup_payload *) skb->data;
167+
hsr = port->hsr;
169168

170169
if (node && !ether_addr_equal(node->MacAddressA, hsr_sp->MacAddressA)) {
171170
/* Node has changed its AddrA, frame was received from SlaveB */
@@ -174,16 +173,16 @@ struct hsr_node *hsr_merge_node(struct hsr_priv *hsr,
174173
node = NULL;
175174
}
176175

177-
if (node && (dev_idx == node->AddrB_if) &&
176+
if (node && (port->type == node->AddrB_port) &&
178177
!ether_addr_equal(node->MacAddressB, hsr_ethsup->ethhdr.h_source)) {
179178
/* Cables have been swapped */
180179
list_del_rcu(&node->mac_list);
181180
kfree_rcu(node, rcu_head);
182181
node = NULL;
183182
}
184183

185-
if (node && (dev_idx != node->AddrB_if) &&
186-
(node->AddrB_if != HSR_DEV_NONE) &&
184+
if (node && (port->type != node->AddrB_port) &&
185+
(node->AddrB_port != HSR_PT_NONE) &&
187186
!ether_addr_equal(node->MacAddressA, hsr_ethsup->ethhdr.h_source)) {
188187
/* Cables have been swapped */
189188
list_del_rcu(&node->mac_list);
@@ -200,7 +199,7 @@ struct hsr_node *hsr_merge_node(struct hsr_priv *hsr,
200199
* address. Node is PICS_SUBS capable; merge its AddrB.
201200
*/
202201
ether_addr_copy(node->MacAddressB, hsr_ethsup->ethhdr.h_source);
203-
node->AddrB_if = dev_idx;
202+
node->AddrB_port = port->type;
204203
return node;
205204
}
206205

@@ -211,17 +210,15 @@ struct hsr_node *hsr_merge_node(struct hsr_priv *hsr,
211210
ether_addr_copy(node->MacAddressA, hsr_sp->MacAddressA);
212211
ether_addr_copy(node->MacAddressB, hsr_ethsup->ethhdr.h_source);
213212
if (!ether_addr_equal(hsr_sp->MacAddressA, hsr_ethsup->ethhdr.h_source))
214-
node->AddrB_if = dev_idx;
215-
else
216-
node->AddrB_if = HSR_DEV_NONE;
213+
node->AddrB_port = port->type;
217214

218215
/* We are only interested in time diffs here, so use current jiffies
219216
* as initialization. (0 could trigger an spurious ring error warning).
220217
*/
221218
now = jiffies;
222-
for (i = 0; i < HSR_MAX_SLAVE; i++)
219+
for (i = 0; i < HSR_PT_PORTS; i++)
223220
node->time_in[i] = now;
224-
for (i = 0; i < HSR_MAX_DEV; i++)
221+
for (i = 0; i < HSR_PT_PORTS; i++)
225222
node->seq_out[i] = ntohs(hsr_ethsup->hsr_sup.sequence_nr) - 1;
226223

227224
list_add_tail_rcu(&node->mac_list, &hsr->node_db);
@@ -265,13 +262,13 @@ void hsr_addr_subst_source(struct hsr_priv *hsr, struct sk_buff *skb)
265262
* which "side" the different interfaces are.
266263
*/
267264
void hsr_addr_subst_dest(struct hsr_priv *hsr, struct ethhdr *ethhdr,
268-
enum hsr_dev_idx dev_idx)
265+
struct hsr_port *port)
269266
{
270267
struct hsr_node *node;
271268

272269
rcu_read_lock();
273270
node = find_node_by_AddrA(&hsr->node_db, ethhdr->h_dest);
274-
if (node && (node->AddrB_if == dev_idx))
271+
if (node && (node->AddrB_port == port->type))
275272
ether_addr_copy(ethhdr->h_dest, node->MacAddressB);
276273
rcu_read_unlock();
277274
}
@@ -295,14 +292,10 @@ static bool seq_nr_after(u16 a, u16 b)
295292
#define seq_nr_before_or_eq(a, b) (!seq_nr_after((a), (b)))
296293

297294

298-
void hsr_register_frame_in(struct hsr_node *node, enum hsr_dev_idx dev_idx)
295+
void hsr_register_frame_in(struct hsr_node *node, struct hsr_port *port)
299296
{
300-
if ((dev_idx < 0) || (dev_idx >= HSR_MAX_SLAVE)) {
301-
WARN_ONCE(1, "%s: Invalid dev_idx (%d)\n", __func__, dev_idx);
302-
return;
303-
}
304-
node->time_in[dev_idx] = jiffies;
305-
node->time_in_stale[dev_idx] = false;
297+
node->time_in[port->type] = jiffies;
298+
node->time_in_stale[port->type] = false;
306299
}
307300

308301

@@ -314,52 +307,45 @@ void hsr_register_frame_in(struct hsr_node *node, enum hsr_dev_idx dev_idx)
314307
* 0 otherwise, or
315308
* negative error code on error
316309
*/
317-
int hsr_register_frame_out(struct hsr_node *node, enum hsr_dev_idx dev_idx,
310+
int hsr_register_frame_out(struct hsr_node *node, struct hsr_port *port,
318311
struct sk_buff *skb)
319312
{
320313
struct hsr_ethhdr *hsr_ethhdr;
321314
u16 sequence_nr;
322315

323-
if ((dev_idx < 0) || (dev_idx >= HSR_MAX_DEV)) {
324-
WARN_ONCE(1, "%s: Invalid dev_idx (%d)\n", __func__, dev_idx);
325-
return -EINVAL;
326-
}
327316
if (!skb_mac_header_was_set(skb)) {
328317
WARN_ONCE(1, "%s: Mac header not set\n", __func__);
329318
return -EINVAL;
330319
}
331320
hsr_ethhdr = (struct hsr_ethhdr *) skb_mac_header(skb);
332321

333322
sequence_nr = ntohs(hsr_ethhdr->hsr_tag.sequence_nr);
334-
if (seq_nr_before_or_eq(sequence_nr, node->seq_out[dev_idx]))
323+
if (seq_nr_before_or_eq(sequence_nr, node->seq_out[port->type]))
335324
return 1;
336325

337-
node->seq_out[dev_idx] = sequence_nr;
326+
node->seq_out[port->type] = sequence_nr;
338327
return 0;
339328
}
340329

341330

342-
343-
static bool is_late(struct hsr_node *node, enum hsr_dev_idx dev_idx)
331+
static struct hsr_port *get_late_port(struct hsr_priv *hsr,
332+
struct hsr_node *node)
344333
{
345-
enum hsr_dev_idx other;
346-
347-
if (node->time_in_stale[dev_idx])
348-
return true;
349-
350-
if (dev_idx == HSR_DEV_SLAVE_A)
351-
other = HSR_DEV_SLAVE_B;
352-
else
353-
other = HSR_DEV_SLAVE_A;
354-
355-
if (node->time_in_stale[other])
356-
return false;
334+
if (node->time_in_stale[HSR_PT_SLAVE_A])
335+
return hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A);
336+
if (node->time_in_stale[HSR_PT_SLAVE_B])
337+
return hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
338+
339+
if (time_after(node->time_in[HSR_PT_SLAVE_B],
340+
node->time_in[HSR_PT_SLAVE_A] +
341+
msecs_to_jiffies(MAX_SLAVE_DIFF)))
342+
return hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A);
343+
if (time_after(node->time_in[HSR_PT_SLAVE_A],
344+
node->time_in[HSR_PT_SLAVE_B] +
345+
msecs_to_jiffies(MAX_SLAVE_DIFF)))
346+
return hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
357347

358-
if (time_after(node->time_in[other], node->time_in[dev_idx] +
359-
msecs_to_jiffies(MAX_SLAVE_DIFF)))
360-
return true;
361-
362-
return false;
348+
return NULL;
363349
}
364350

365351

@@ -370,6 +356,7 @@ void hsr_prune_nodes(unsigned long data)
370356
{
371357
struct hsr_priv *hsr;
372358
struct hsr_node *node;
359+
struct hsr_port *port;
373360
unsigned long timestamp;
374361
unsigned long time_a, time_b;
375362

@@ -378,35 +365,33 @@ void hsr_prune_nodes(unsigned long data)
378365
rcu_read_lock();
379366
list_for_each_entry_rcu(node, &hsr->node_db, mac_list) {
380367
/* Shorthand */
381-
time_a = node->time_in[HSR_DEV_SLAVE_A];
382-
time_b = node->time_in[HSR_DEV_SLAVE_B];
368+
time_a = node->time_in[HSR_PT_SLAVE_A];
369+
time_b = node->time_in[HSR_PT_SLAVE_B];
383370

384371
/* Check for timestamps old enough to risk wrap-around */
385372
if (time_after(jiffies, time_a + MAX_JIFFY_OFFSET/2))
386-
node->time_in_stale[HSR_DEV_SLAVE_A] = true;
373+
node->time_in_stale[HSR_PT_SLAVE_A] = true;
387374
if (time_after(jiffies, time_b + MAX_JIFFY_OFFSET/2))
388-
node->time_in_stale[HSR_DEV_SLAVE_B] = true;
375+
node->time_in_stale[HSR_PT_SLAVE_B] = true;
389376

390377
/* Get age of newest frame from node.
391378
* At least one time_in is OK here; nodes get pruned long
392379
* before both time_ins can get stale
393380
*/
394381
timestamp = time_a;
395-
if (node->time_in_stale[HSR_DEV_SLAVE_A] ||
396-
(!node->time_in_stale[HSR_DEV_SLAVE_B] &&
382+
if (node->time_in_stale[HSR_PT_SLAVE_A] ||
383+
(!node->time_in_stale[HSR_PT_SLAVE_B] &&
397384
time_after(time_b, time_a)))
398385
timestamp = time_b;
399386

400387
/* Warn of ring error only as long as we get frames at all */
401388
if (time_is_after_jiffies(timestamp +
402389
msecs_to_jiffies(1.5*MAX_SLAVE_DIFF))) {
403-
404-
if (is_late(node, HSR_DEV_SLAVE_A))
405-
hsr_nl_ringerror(hsr, node->MacAddressA,
406-
HSR_DEV_SLAVE_A);
407-
else if (is_late(node, HSR_DEV_SLAVE_B))
408-
hsr_nl_ringerror(hsr, node->MacAddressA,
409-
HSR_DEV_SLAVE_B);
390+
rcu_read_lock();
391+
port = get_late_port(hsr, node);
392+
if (port != NULL)
393+
hsr_nl_ringerror(hsr, node->MacAddressA, port);
394+
rcu_read_unlock();
410395
}
411396

412397
/* Prune old entries */
@@ -455,7 +440,7 @@ int hsr_get_node_data(struct hsr_priv *hsr,
455440
u16 *if2_seq)
456441
{
457442
struct hsr_node *node;
458-
struct net_device *slave;
443+
struct hsr_port *port;
459444
unsigned long tdiff;
460445

461446

@@ -468,8 +453,8 @@ int hsr_get_node_data(struct hsr_priv *hsr,
468453

469454
ether_addr_copy(addr_b, node->MacAddressB);
470455

471-
tdiff = jiffies - node->time_in[HSR_DEV_SLAVE_A];
472-
if (node->time_in_stale[HSR_DEV_SLAVE_A])
456+
tdiff = jiffies - node->time_in[HSR_PT_SLAVE_A];
457+
if (node->time_in_stale[HSR_PT_SLAVE_A])
473458
*if1_age = INT_MAX;
474459
#if HZ <= MSEC_PER_SEC
475460
else if (tdiff > msecs_to_jiffies(INT_MAX))
@@ -478,8 +463,8 @@ int hsr_get_node_data(struct hsr_priv *hsr,
478463
else
479464
*if1_age = jiffies_to_msecs(tdiff);
480465

481-
tdiff = jiffies - node->time_in[HSR_DEV_SLAVE_B];
482-
if (node->time_in_stale[HSR_DEV_SLAVE_B])
466+
tdiff = jiffies - node->time_in[HSR_PT_SLAVE_B];
467+
if (node->time_in_stale[HSR_PT_SLAVE_B])
483468
*if2_age = INT_MAX;
484469
#if HZ <= MSEC_PER_SEC
485470
else if (tdiff > msecs_to_jiffies(INT_MAX))
@@ -489,14 +474,15 @@ int hsr_get_node_data(struct hsr_priv *hsr,
489474
*if2_age = jiffies_to_msecs(tdiff);
490475

491476
/* Present sequence numbers as if they were incoming on interface */
492-
*if1_seq = node->seq_out[HSR_DEV_SLAVE_B];
493-
*if2_seq = node->seq_out[HSR_DEV_SLAVE_A];
477+
*if1_seq = node->seq_out[HSR_PT_SLAVE_B];
478+
*if2_seq = node->seq_out[HSR_PT_SLAVE_A];
494479

495-
slave = hsr->slave[node->AddrB_if];
496-
if ((node->AddrB_if != HSR_DEV_NONE) && slave)
497-
*addr_b_ifindex = slave->ifindex;
498-
else
480+
if (node->AddrB_port != HSR_PT_NONE) {
481+
port = hsr_port_get_hsr(hsr, node->AddrB_port);
482+
*addr_b_ifindex = port->dev->ifindex;
483+
} else {
499484
*addr_b_ifindex = -1;
485+
}
500486

501487
rcu_read_unlock();
502488

net/hsr/hsr_framereg.h

+5-7
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,16 @@ struct hsr_node;
1818

1919
struct hsr_node *hsr_find_node(struct list_head *node_db, struct sk_buff *skb);
2020

21-
struct hsr_node *hsr_merge_node(struct hsr_priv *hsr,
22-
struct hsr_node *node,
23-
struct sk_buff *skb,
24-
enum hsr_dev_idx dev_idx);
21+
struct hsr_node *hsr_merge_node(struct hsr_node *node, struct sk_buff *skb,
22+
struct hsr_port *port);
2523

2624
void hsr_addr_subst_source(struct hsr_priv *hsr, struct sk_buff *skb);
2725
void hsr_addr_subst_dest(struct hsr_priv *hsr, struct ethhdr *ethhdr,
28-
enum hsr_dev_idx dev_idx);
26+
struct hsr_port *port);
2927

30-
void hsr_register_frame_in(struct hsr_node *node, enum hsr_dev_idx dev_idx);
28+
void hsr_register_frame_in(struct hsr_node *node, struct hsr_port *port);
3129

32-
int hsr_register_frame_out(struct hsr_node *node, enum hsr_dev_idx dev_idx,
30+
int hsr_register_frame_out(struct hsr_node *node, struct hsr_port *port,
3331
struct sk_buff *skb);
3432

3533
void hsr_prune_nodes(unsigned long data);

0 commit comments

Comments
 (0)