Thomas Schmitt 2020-07-07 13:27:20 +00:00
parent da632d90c5
commit 0bc2476033
1 changed files with 161 additions and 0 deletions

161
ConcurrentLinuxSr.md Normal file

@ -0,0 +1,161 @@
# The problems with concurrent burns on Linux
Beginning with high version numbers of Linux kernel 2.6 and up to
at least kernel 4.3.0 there is a performance problem when more than
one optical drive is used for burning or reading via libburn at the same time.
The overall throughput is less than the throughput of the slowest drive
when it is used as only one.
This affects SATA and USB attached drives alike. Most probably also IDE
attached ones.
## Kernel theory
The most plausible explanation for the problem is the introduction
of a global lock for all optical drives which is held during the
whole transaction time of `ioctl(SG_IO)`.
This ioctl is used by libburn to send SCSI commands to the burner
drive. So each single burner blocks the other libburn processes
until it has ended its transaction.
See the problematic changeset which affected `drivers/scsi/sr.c` among
many other kernel parts:
https://lkml.org/lkml/2010/9/14/338
and the summary of consequences with remedy proposal:
http://marc.info/?l=linux-scsi&m=135705061804384&w=2
Obviously the deprecated device file family `/dev/sg*` does not have such
a lock.
# Consequences for libburn
## Using /dev/sg* against all good advise
The libburn call `burn_preset_device_open()`, cdrskin option
`drive_scsi_dev_family=`, and xorriso command `-scsi_dev_family`
can cause libburn to use `/dev/sg*` instead of `/dev/sr*`.
Without such special setting a `/dev/sg*` address given by the user would
be mapped to the corresponding `/dev/sr*`.
These runs of version 1.4.4 or higher can coexist without throughput
problems:
```
xorriso -scsi_dev_family sg -dev /dev/sr0 -map ./data /data
```
```
xorriso -as cdrecord drive_scsi_dev_family=sg dev=/dev/sr1 -v image2.iso
```
```
cdrskin drive_scsi_dev_family=sg dev=/dev/sr3 -v image3.iso
```
### /dev/sg with older versions of cdrskin
A bug in libburn-0.5.2 to 1.4.2 prevented automatic conversion from `/dev/sr*`
addresses to `/dev/sg*` addresses if `drive_scsi_dev_family=sg` is given.
xorriso up to version 1.4.2 did not offer the opportunity to use `/dev/sg*`.
Nevertheless it is possible to let older cdrskin versions work with `/dev/sg*`:
```
$ cdrskin drive_scsi_dev_family=sg --devices
...
0 dev='/dev/sg2' rwrw-- : 'HL-DT-ST' 'BDDVDRW GGC-H20L'
1 dev='/dev/sg3' rwrw-- : 'HL-DT-ST' 'DVDRAM GH24NSC0'
2 dev='/dev/sg4' rwrw-- : 'ASUS ' 'BW-16D1HT'
3 dev='/dev/sg5' rwrw-- : 'HL-DT-ST' 'BD-RE GGW-H20L'
4 dev='/dev/sg6' rwrw-- : 'Optiarc ' 'BD RW BD-5300S'
```
```
$ cdrskin drive_scsi_dev_family=sg dev=/dev/sg2 -v image1.iso
$ cdrskin drive_scsi_dev_family=sg dev=/dev/sg3 -v image2.iso
$ cdrskin drive_scsi_dev_family=sg dev=/dev/sg6 -v image3.iso
```
Meanwhile the releases on [release page](Releases)
have the bug fixed and xorriso augmented by a new command.
## Staying with /dev/sr* as bad as it is
Despite the fine performance of `/dev/sg*` it remains desirable to use
`/dev/sr*` because `/dev/sg` is deprecated by the kernel developers,
the translation from `/dev/sr` to `/dev/sg` is not guaranteed to work in future,
and `/dev/sr*` is better coordinated with `mount(8)` and `open(2)` for
`read(2)`.
So long lasting SCSI transactions via `/dev/sr*` cause long
delays of communication with the other drives. Some of these delays
cannot be avoided.
E.g. the SCSI command to eject the tray needs several seconds to be
completed.
Another long delay can be circumvented, though:
If the buffer of a drive is nearly full and a WRITE command
arrives, then the drive may delay the reply until there is room
in the buffer for the next WRITE command.
Depending on the firmware and buffer size, this may last quite some
time. Further the time granularity of lock waiting seems quite coarse.
These long waiting WRITE commands can be avoided if libburn keeps
itself from filling the drive buffer to a level where the firmware
would begin to delay the reply.
xorriso command `-modesty_on_drive`, cdrskin option
`modesty_on_drive=`, and libburn call `burn_drive_set_buffer_waiting()`
apply a strategy which stems from the days of IDE when the slow CD drive
clogged the IDE controller which it shared with a HDD.
Example:
```
-modesty_on_drive on:min_percent=90:max_percent=95
```
Some drive firmwares work well with partly empty buffer, some don't.
Regrettably there is no similar remedy known for reading from /dev/sr*
via ioctl(SG_IO).
### Parameter considerations
Those drives which can work well with `-modesty_on_drive` still may need
adjustment of the modesty parameters.
The threshold for delaying further WRITE commands is controlled by
parameter `max_percent`. The threshold for resuming to send WRITE
commands is `min_percent`.
So if `min_percent=90:max_percent=95` does not show the desired effect
of reaching about 80 to 90 percent of the throughput of an undisturbed
burn run of a single burner, then one has to try variations.
Keep in mind that `min_percent` has to stay lower than `max_percent`.
Drives have been observed to report their buffer fill too low. This
risks to send a long blocking WRITE command by mistake.
A lower `max_percent` percent value may compensate.
```
-modesty_on_drive on:min_percent=75:max_percent=80
```
Drives have been observed to become even slower by waiting for more
input before writing if their buffer is not full enough.
A higher `min_percent` may help.
```
-modesty_on_drive on:min_percent=95:max_percent=97
```
Drives have been observed to slow down their write speed if the
input comes in small amounts with some short waiting time inbetween.
A larger gap between `min_percent` and `max_percent` may help
to get larger write amounts without intermediate waiting.
```
-modesty_on_drive on:min_percent=75:max_percent=95
```
Finally there are drives which perform poorly with stream recording if
their buffer is not completely full. This means that they will not
be able to burn DVD-RAM, BD-RE, or formatted BD-R at full nominal speed
if `-modesty_on_drive` is set to `on`.