Acquire master->io_sem lock where needed

With this, we should have in place so that master->io_sem is always held when
accessing master->datagram_queue.

Note, the use of master->master_sem in ec_ioctl_send() and
ec_ioctl_receive() were wrong (introduced in commit cef602586c). The
only thing needing to be synchronized there is the access to
master->datagram_queue, which is protected by master->io_sem.

This corresponds roughly to the fixes for stable-1.5 that are seen in
https://gitlab.com/etherlab.org/ethercat/-/merge_requests/36 .
This commit is contained in:
Esben Haabendal 2021-06-24 13:45:08 +02:00 committed by Rasmus Villemoes
parent e243c6b7db
commit 2372382259
2 changed files with 32 additions and 10 deletions

View File

@ -2112,7 +2112,7 @@ static ATTRIBUTES int ec_ioctl_send(
/* Locking added as send is likely to be used by more than
one application tasks */
if (ec_ioctl_lock_down_interruptible(&master->master_sem))
if (ec_ioctl_lock_down_interruptible(&master->io_sem))
return -EINTR;
if (master->send_cb != NULL) {
@ -2121,7 +2121,7 @@ static ATTRIBUTES int ec_ioctl_send(
} else
sent_bytes = ecrt_master_send(master);
ec_ioctl_lock_up(&master->master_sem);
ec_ioctl_lock_up(&master->io_sem);
if (copy_to_user((void __user *) arg, &sent_bytes, sizeof(sent_bytes))) {
return -EFAULT;
@ -2148,7 +2148,7 @@ static ATTRIBUTES int ec_ioctl_receive(
/* Locking added as receive is likely to be used by more than
one application tasks */
if (ec_ioctl_lock_down_interruptible(&master->master_sem))
if (ec_ioctl_lock_down_interruptible(&master->io_sem))
return -EINTR;
if (master->receive_cb != NULL)
@ -2156,7 +2156,8 @@ static ATTRIBUTES int ec_ioctl_receive(
else
ecrt_master_receive(master);
ec_ioctl_lock_up(&master->master_sem);
ec_ioctl_lock_up(&master->io_sem);
return 0;
}
@ -2255,7 +2256,10 @@ static ATTRIBUTES int ec_ioctl_sync_ref(
return -EPERM;
}
if (ec_ioctl_lock_down_interruptible(&master->io_sem))
return -EINTR;
ecrt_master_sync_reference_clock(master);
ec_ioctl_lock_up(&master->io_sem);
return 0;
}
@ -2280,7 +2284,10 @@ static ATTRIBUTES int ec_ioctl_sync_ref_to(
return -EFAULT;
}
if (ec_ioctl_lock_down_interruptible(&master->io_sem))
return -EINTR;
ecrt_master_sync_reference_clock_to(master, time);
ec_ioctl_lock_up(&master->io_sem);
return 0;
}
@ -2300,7 +2307,10 @@ static ATTRIBUTES int ec_ioctl_sync_slaves(
return -EPERM;
}
if (ec_ioctl_lock_down_interruptible(&master->io_sem))
return -EINTR;
ecrt_master_sync_slave_clocks(master);
ec_ioctl_lock_up(&master->io_sem);
return 0;
}
@ -2351,7 +2361,10 @@ static ATTRIBUTES int ec_ioctl_64bit_ref_clock_time_queue(
return -EPERM;
}
if (ec_ioctl_lock_down_interruptible(&master->io_sem))
return -EINTR;
ecrt_master_64bit_reference_clock_time_queue(master);
ec_ioctl_lock_up(&master->io_sem);
return 0;
}
@ -2402,7 +2415,10 @@ static ATTRIBUTES int ec_ioctl_sync_mon_queue(
return -EPERM;
}
if (ec_ioctl_lock_down_interruptible(&master->io_sem))
return -EINTR;
ecrt_master_sync_monitor_queue(master);
ec_ioctl_lock_up(&master->io_sem);
return 0;
}
@ -3515,10 +3531,13 @@ static ATTRIBUTES int ec_ioctl_domain_queue(
return -ENOENT;
}
ecrt_domain_queue(domain);
ec_ioctl_lock_up(&master->master_sem);
if (ec_ioctl_lock_down_interruptible(&master->io_sem))
return -EINTR;
ecrt_domain_queue(domain);
ec_ioctl_lock_up(&master->io_sem);
return 0;
}
@ -4236,7 +4255,10 @@ static ATTRIBUTES int ec_ioctl_voe_exec(
return -ENOENT;
}
if (ec_ioctl_lock_down_interruptible(&master->io_sem))
return -EINTR;
data.state = ecrt_voe_handler_execute(voe);
ec_ioctl_lock_up(&master->io_sem);
if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
data.size = ecrt_voe_handler_data_size(voe);
else

View File

@ -564,9 +564,7 @@ void ec_master_internal_send_cb(
)
{
ec_master_t *master = (ec_master_t *) cb_data;
ec_lock_down(&master->io_sem);
ecrt_master_send_ext(master);
ec_lock_up(&master->io_sem);
}
/*****************************************************************************/
@ -578,9 +576,7 @@ void ec_master_internal_receive_cb(
)
{
ec_master_t *master = (ec_master_t *) cb_data;
ec_lock_down(&master->io_sem);
ecrt_master_receive(master);
ec_lock_up(&master->io_sem);
}
/*****************************************************************************/
@ -1889,7 +1885,9 @@ static int ec_master_eoe_thread(void *priv_data)
}
// receive datagrams
ec_lock_down(&master->io_sem);
master->receive_cb(master->cb_data);
ec_lock_up(&master->io_sem);
// actual EoE processing
sth_to_send = 0;
@ -1904,9 +1902,11 @@ static int ec_master_eoe_thread(void *priv_data)
}
if (sth_to_send) {
ec_lock_down(&master->io_sem);
list_for_each_entry(eoe, &master->eoe_handlers, list) {
ec_eoe_queue(eoe);
}
ec_lock_up(&master->io_sem);
// (try to) send datagrams
ec_lock_down(&master->ext_queue_sem);
master->send_cb(master->cb_data);