Add lock protection of domain->datagram_pairs
While domain->datagram_pairs was previously partly protected by the master->master_sem lock (it was not done consistently though), the fix to protection of master->datagram_queue made it even worse. This change adds protection of domain->datagram_pairs using a new lock dedicated to this. The domain->datagram_pairs_lock is acquired in the actual functions accessing the domain->datagram_pairs, and this currently means that it is acquired both in situations where master->master_sem is held and in situations where master->io_sem is held.
This commit is contained in:
parent
2372382259
commit
19b8ddea18
|
|
@ -76,6 +76,7 @@ void ec_domain_init(
|
|||
domain->data_origin = EC_ORIG_INTERNAL;
|
||||
domain->logical_base_address = 0x00000000;
|
||||
INIT_LIST_HEAD(&domain->datagram_pairs);
|
||||
ec_lock_init(&domain->datagram_pairs_lock);
|
||||
for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
|
||||
dev_idx++) {
|
||||
domain->working_counter[dev_idx] = 0x0000;
|
||||
|
|
@ -98,12 +99,14 @@ void ec_domain_clear(ec_domain_t *domain /**< EtherCAT domain */)
|
|||
{
|
||||
ec_datagram_pair_t *datagram_pair, *next_pair;
|
||||
|
||||
ec_lock_down(&domain->datagram_pairs_lock);
|
||||
// dequeue and free datagrams
|
||||
list_for_each_entry_safe(datagram_pair, next_pair,
|
||||
&domain->datagram_pairs, list) {
|
||||
ec_datagram_pair_clear(datagram_pair);
|
||||
kfree(datagram_pair);
|
||||
}
|
||||
ec_lock_up(&domain->datagram_pairs_lock);
|
||||
|
||||
ec_domain_clear_data(domain);
|
||||
}
|
||||
|
|
@ -216,7 +219,9 @@ int ec_domain_add_datagram_pair(
|
|||
datagram_pair->expected_working_counter);
|
||||
|
||||
|
||||
ec_lock_down(&domain->datagram_pairs_lock);
|
||||
list_add_tail(&datagram_pair->list, &domain->datagram_pairs);
|
||||
ec_lock_up(&domain->datagram_pairs_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -389,6 +394,7 @@ int ec_domain_finish(
|
|||
domain->logical_base_address, domain->data_size,
|
||||
domain->expected_working_counter);
|
||||
|
||||
ec_lock_down(&domain->datagram_pairs_lock);
|
||||
list_for_each_entry(datagram_pair, &domain->datagram_pairs, list) {
|
||||
const ec_datagram_t *datagram =
|
||||
&datagram_pair->datagrams[EC_DEVICE_MAIN];
|
||||
|
|
@ -397,6 +403,7 @@ int ec_domain_finish(
|
|||
EC_READ_U32(datagram->address), datagram->data_size,
|
||||
ec_datagram_type_string(datagram), datagram);
|
||||
}
|
||||
ec_lock_up(&domain->datagram_pairs_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -551,6 +558,7 @@ void ecrt_domain_process(ec_domain_t *domain)
|
|||
EC_MASTER_DBG(domain->master, 1, "domain %u process\n", domain->index);
|
||||
#endif
|
||||
|
||||
ec_lock_down(&domain->datagram_pairs_lock);
|
||||
list_for_each_entry(pair, &domain->datagram_pairs, list) {
|
||||
#if EC_MAX_NUM_DEVICES > 1
|
||||
datagram_pair_wc = ec_datagram_pair_process(pair, wc_sum);
|
||||
|
|
@ -638,6 +646,7 @@ void ecrt_domain_process(ec_domain_t *domain)
|
|||
}
|
||||
#endif // EC_MAX_NUM_DEVICES > 1
|
||||
}
|
||||
ec_lock_up(&domain->datagram_pairs_lock);
|
||||
|
||||
#if EC_MAX_NUM_DEVICES > 1
|
||||
redundant_wc = 0;
|
||||
|
|
@ -726,6 +735,7 @@ void ecrt_domain_queue(ec_domain_t *domain)
|
|||
ec_datagram_pair_t *datagram_pair;
|
||||
ec_device_index_t dev_idx;
|
||||
|
||||
ec_lock_down(&domain->datagram_pairs_lock);
|
||||
list_for_each_entry(datagram_pair, &domain->datagram_pairs, list) {
|
||||
|
||||
#if EC_MAX_NUM_DEVICES > 1
|
||||
|
|
@ -747,6 +757,7 @@ void ecrt_domain_queue(ec_domain_t *domain)
|
|||
&datagram_pair->datagrams[dev_idx]);
|
||||
}
|
||||
}
|
||||
ec_lock_up(&domain->datagram_pairs_lock);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "datagram.h"
|
||||
#include "master.h"
|
||||
#include "fmmu_config.h"
|
||||
#include "locks.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -65,6 +66,8 @@ struct ec_domain
|
|||
process data. */
|
||||
struct list_head datagram_pairs; /**< Datagrams pairs (main/backup) for
|
||||
process data exchange. */
|
||||
ec_lock_t datagram_pairs_lock; /**< Semaphore protecting the
|
||||
datagram_pairs. */
|
||||
uint16_t working_counter[EC_MAX_NUM_DEVICES]; /**< Last working counter
|
||||
values. */
|
||||
uint16_t expected_working_counter; /**< Expected working counter. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue