Skip to content

Commit 8191700

Browse files
target: Speedup Target.write_value()
Avoid an execute() by doing the check in the same command. This also allows to return early if the write is fast, and to extend for longer if the write is slow. The speed at which you can observe a write in sysfs depends on the backing kernel handlers, so there is a wide variety of situations.
1 parent 301d43d commit 8191700

File tree

1 file changed

+29
-5
lines changed

1 file changed

+29
-5
lines changed

devlib/target.py

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -736,12 +736,36 @@ def batch_revertable_write_value(self, kwargs_list):
736736

737737
def write_value(self, path, value, verify=True):
738738
value = str(value)
739-
self.execute('echo {} > {}'.format(quote(value), quote(path)), check_exit_code=False, as_root=True)
739+
740740
if verify:
741-
output = self.read_value(path)
742-
if not output == value:
743-
message = 'Could not set the value of {} to "{}" (read "{}")'.format(path, value, output)
744-
raise TargetStableError(message)
741+
# Check in a loop for a while since updates to sysfs files can take
742+
# some time to be observed, typically when a write triggers a
743+
# lengthy kernel-side request, and the read is based on some piece
744+
# of state that may take some time to be updated by the write
745+
# request, such as hotplugging a CPU.
746+
cmd = '''
747+
orig=$(cat {path} 2>/dev/null || printf "")
748+
printf "%s" {value} > {path}
749+
if [ {value} != "$orig" ]; then
750+
trials=0
751+
while [ "$(cat {path} 2>/dev/null)" != {value} ]; do
752+
if [ $trials -ge 10 ]; then
753+
cat {path}
754+
exit 1
755+
fi
756+
sleep 0.01
757+
trials=$((trials + 1))
758+
done
759+
fi
760+
'''
761+
else:
762+
cmd = 'printf "%s" {value} > {path}'
763+
cmd = cmd.format(path=quote(path), value=quote(value))
764+
765+
out = self.execute(cmd, check_exit_code=False, as_root=True)
766+
if verify and out:
767+
message = 'Could not set the value of {} to "{}" (read "{}")'.format(path, value, out)
768+
raise TargetStableError(message)
745769

746770
def reset(self):
747771
try:

0 commit comments

Comments
 (0)