Cherry-picked MR 188 (injection-semaphore) from 1.7.
This commit is contained in:
parent
98563a2f0d
commit
cf19168844
|
|
@ -61,6 +61,23 @@
|
||||||
rt_mutex_lock_interruptible(lock, 0)
|
rt_mutex_lock_interruptible(lock, 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 47)
|
||||||
|
|
||||||
|
#define smp_store_release(p, v) \
|
||||||
|
do { \
|
||||||
|
smp_mb(); \
|
||||||
|
ACCESS_ONCE(*p) = (v); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define smp_load_acquire(p) \
|
||||||
|
({ \
|
||||||
|
typeof(*p) ___p1 = ACCESS_ONCE(*p); \
|
||||||
|
smp_mb(); \
|
||||||
|
___p1; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "master.h"
|
#include "master.h"
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
@ -195,6 +212,7 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
|
||||||
master->phase = EC_ORPHANED;
|
master->phase = EC_ORPHANED;
|
||||||
master->active = 0;
|
master->active = 0;
|
||||||
master->config_changed = 0;
|
master->config_changed = 0;
|
||||||
|
|
||||||
master->injection_seq_fsm = 0;
|
master->injection_seq_fsm = 0;
|
||||||
master->injection_seq_rt = 0;
|
master->injection_seq_rt = 0;
|
||||||
|
|
||||||
|
|
@ -1596,6 +1614,7 @@ static int ec_master_idle_thread(void *priv_data)
|
||||||
static int ec_master_operation_thread(void *priv_data)
|
static int ec_master_operation_thread(void *priv_data)
|
||||||
{
|
{
|
||||||
ec_master_t *master = (ec_master_t *) priv_data;
|
ec_master_t *master = (ec_master_t *) priv_data;
|
||||||
|
unsigned int seq_rt;
|
||||||
|
|
||||||
EC_MASTER_DBG(master, 1, "Operation thread running"
|
EC_MASTER_DBG(master, 1, "Operation thread running"
|
||||||
" with fsm interval = %u us, max data size=%zu\n",
|
" with fsm interval = %u us, max data size=%zu\n",
|
||||||
|
|
@ -1604,7 +1623,11 @@ static int ec_master_operation_thread(void *priv_data)
|
||||||
while (!kthread_should_stop()) {
|
while (!kthread_should_stop()) {
|
||||||
ec_datagram_output_stats(&master->fsm_datagram);
|
ec_datagram_output_stats(&master->fsm_datagram);
|
||||||
|
|
||||||
if (master->injection_seq_rt == master->injection_seq_fsm) {
|
/* Use smp_load_acquire() to prevent re-ordering.
|
||||||
|
* https://gitlab.com/etherlab.org/ethercat/-/work_items/168 */
|
||||||
|
seq_rt = smp_load_acquire(&master->injection_seq_rt);
|
||||||
|
if (seq_rt == master->injection_seq_fsm) { // was injected
|
||||||
|
|
||||||
// output statistics
|
// output statistics
|
||||||
ec_master_output_stats(master);
|
ec_master_output_stats(master);
|
||||||
|
|
||||||
|
|
@ -1616,7 +1639,9 @@ static int ec_master_operation_thread(void *priv_data)
|
||||||
if (ec_fsm_master_exec(&master->fsm)) {
|
if (ec_fsm_master_exec(&master->fsm)) {
|
||||||
// Inject datagrams (let the RT thread queue them, see
|
// Inject datagrams (let the RT thread queue them, see
|
||||||
// ecrt_master_send())
|
// ecrt_master_send())
|
||||||
master->injection_seq_fsm++;
|
// re-ordering-safe version of `master->injection_seq_fsm++`
|
||||||
|
smp_store_release(&master->injection_seq_fsm,
|
||||||
|
master->injection_seq_fsm + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ec_master_exec_slave_fsms(master);
|
ec_master_exec_slave_fsms(master);
|
||||||
|
|
@ -2436,11 +2461,14 @@ int ecrt_master_send(ec_master_t *master)
|
||||||
{
|
{
|
||||||
ec_datagram_t *datagram, *n;
|
ec_datagram_t *datagram, *n;
|
||||||
ec_device_index_t dev_idx;
|
ec_device_index_t dev_idx;
|
||||||
|
unsigned int seq_fsm;
|
||||||
|
|
||||||
if (master->injection_seq_rt != master->injection_seq_fsm) {
|
seq_fsm = smp_load_acquire(&master->injection_seq_fsm);
|
||||||
|
if (master->injection_seq_rt != seq_fsm) {
|
||||||
// inject datagram produced by master FSM
|
// inject datagram produced by master FSM
|
||||||
ec_master_queue_datagram(master, &master->fsm_datagram);
|
ec_master_queue_datagram(master, &master->fsm_datagram);
|
||||||
master->injection_seq_rt = master->injection_seq_fsm;
|
|
||||||
|
smp_store_release(&master->injection_seq_rt, seq_fsm);
|
||||||
}
|
}
|
||||||
|
|
||||||
ec_master_inject_external_datagrams(master);
|
ec_master_inject_external_datagrams(master);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue