Table of Contents
The problems with concurrent burns on Linux
Beginning with high version numbers of Linux kernel 2.6 and up to probably kernel 5.6 or 5.7 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.
Relief can be expected by a commit of Feb 24, 2020:
At that time, the kernel version was in the 5.6-rc era.
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 have the bug fixed and xorriso augmented by a new command.
Changing kernel source to make /dev/sr* as fast as /dev/sg*
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)
.
If you are able to compile an own Linux kernel, then the remedy is quite
simple. In the source code of kernel 4.19 i edited drivers/scsi/sr.c
,
included <scsi/sg.h>
which defines SG_IO, and skipped the mutex calls in
function sr_block_ioctl()
in case of SG_IO:
...
#include <scsi/sg.h> /* For number value of ioctl cmd SG_IO */
...
static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
unsigned long arg)
{
...
if (cmd != SG_IO)
mutex_lock(&sr_mutex);
...
if (cmd != SG_IO)
mutex_unlock(&sr_mutex);
...
}
Staying with /dev/sr* as bad as it is
Without such a kernel change, 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
.