Skip to content

Commit

Permalink
sleep briefly while flashing
Browse files Browse the repository at this point in the history
Summary:
Go idle periodically when flashing the image, to allow other work
on the system to happen, for example SPI I/O.  For a 32MB flash
image, this would result in an extra 8s of idle time during wipe plus
8s during flashing.  For S434121.

Test Plan:
```
0 ~/local/openbmc/tools/flashy $ ./build.sh && ./build_dev.sh && go test ./...
?       github.com/facebook/openbmc/tools/flashy/flash_procedure        [no test files]
?       github.com/facebook/openbmc/tools/flashy/lib/logger     [no test files]
?       github.com/facebook/openbmc/tools/flashy/tests  [no test files]
?       github.com/facebook/openbmc/tools/flashy/utilities      [no test files]
ok      github.com/facebook/openbmc/tools/flashy        2.024s
ok      github.com/facebook/openbmc/tools/flashy/checks_and_remediations/bletchley      (cached)
ok      github.com/facebook/openbmc/tools/flashy/checks_and_remediations/common (cached)
ok      github.com/facebook/openbmc/tools/flashy/checks_and_remediations/galaxy100      (cached)
ok      github.com/facebook/openbmc/tools/flashy/checks_and_remediations/grandteton     (cached)
ok      github.com/facebook/openbmc/tools/flashy/checks_and_remediations/wedge100       (cached)
ok      github.com/facebook/openbmc/tools/flashy/checks_and_remediations/yamp   (cached)
ok      github.com/facebook/openbmc/tools/flashy/install        0.007s
ok      github.com/facebook/openbmc/tools/flashy/lib/fileutils  (cached)
ok      github.com/facebook/openbmc/tools/flashy/lib/flash      0.007s
ok      github.com/facebook/openbmc/tools/flashy/lib/flash/flashcp      0.508s
ok      github.com/facebook/openbmc/tools/flashy/lib/flash/flashutils   (cached)
ok      github.com/facebook/openbmc/tools/flashy/lib/flash/flashutils/devices   (cached)
ok      github.com/facebook/openbmc/tools/flashy/lib/step       (cached)
ok      github.com/facebook/openbmc/tools/flashy/lib/utils      (cached)
ok      github.com/facebook/openbmc/tools/flashy/lib/validate   (cached)
ok      github.com/facebook/openbmc/tools/flashy/lib/validate/image     (cached)
ok      github.com/facebook/openbmc/tools/flashy/lib/validate/partition (cached)
0 ~/local/openbmc/tools/flashy $
```

Build ephemeral fbpkg and flash a wedge100 using it:

```
Host                                Workflow ID                           Progress    Status                   Result
----------------------------------  ------------------------------------  ----------  -----------------------  ----------------------
fboss8382003-oob.snc1.facebook.com  b4600065-e674-4696-9378-5c313ae45819  finished    WorkflowStatus.FINISHED  FinishStatus.SUCCEEDED
```
-> https://fburl.com/scuba/openbmc_upgrades/yksvon8b

Reviewed By: kawmarco

Differential Revision: D59927810

fbshipit-source-id: 7db5bb534575d360816a2ec27bea361936fe16dd
  • Loading branch information
doranand authored and facebook-github-bot committed Jul 19, 2024
1 parent 1486cae commit 5074d45
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
22 changes: 21 additions & 1 deletion tools/flashy/lib/flash/flashcp/flashcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
"os"
"regexp"
"syscall"
"time"
"unsafe"

"github.com/facebook/openbmc/tools/flashy/lib/fileutils"
Expand Down Expand Up @@ -83,6 +84,7 @@ type mtd_info_user struct {

const sizeof_mtd_info_user = 32
const sizeof_erase_user_info = 8
const chunkSize = uint32(1048576)

// linux/include/uapi/mtd/mtd-abi.h
var MEMGETINFO = ioctl.IOR('M', 1, sizeof_mtd_info_user)
Expand Down Expand Up @@ -254,6 +256,8 @@ var eraseFlashDevice = func(
imFile imageFile,
roOffset uint32,
) error {
sleepTodo := int32(chunkSize)

log.Printf("Erasing flash device '%v'...", deviceFile.Name())

if m.erasesize == 0 {
Expand Down Expand Up @@ -293,6 +297,18 @@ var eraseFlashDevice = func(
log.Print(errMsg)
return errors.Errorf("%v", errMsg)
}

// For every chunkSize bytes of work done, sleep for 1/4s to
// allow for other work on the system (especially I/O to the
// SPI) to complete.
//
// In practice erasesize will be smaller than chunkSize but
// in any case this will still trigger every so often.
sleepTodo = sleepTodo - int32(m.erasesize);
if sleepTodo <= 0 {
sleepTodo = int32(chunkSize);
utils.Sleep(time.Millisecond * 250);
}
}

log.Printf("Finished erasing flash device '%v'", deviceFile.Name())
Expand All @@ -306,7 +322,6 @@ var flashImage = func(
imFile imageFile,
roOffset uint32,
) error {
const chunkSize = uint32(1048576)
fileSize := uint32(len(imFile.data))

log.Printf("Flashing image '%v' on to flash device '%v'", imFile.name, deviceFile.Name())
Expand Down Expand Up @@ -336,6 +351,11 @@ var flashImage = func(
imFile.name, deviceFile.Name(), n, err,
)
}

// For every chunkSize bytes of work done, sleep for 1/4s to
// allow for other work on the system (especially I/O to the
// SPI) to complete.
utils.Sleep(time.Millisecond * 250);
}

log.Printf("Finished flashing image '%v' on to flash device '%v'",
Expand Down
18 changes: 18 additions & 0 deletions tools/flashy/lib/flash/flashcp/flashcp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"bytes"
"math"
"testing"
"time"
"unsafe"

"github.com/facebook/openbmc/tools/flashy/lib/fileutils"
Expand Down Expand Up @@ -59,6 +60,7 @@ func TestFlashCp(t *testing.T) {
runFlashProcessOrig := runFlashProcess
closeFileOrig := closeFlashDeviceFile
PetWatchdogOrig := utils.PetWatchdog
sleepOrig := utils.Sleep
defer func() {
openFlashDeviceFile = openFileOrig
getMtdInfoUser = getMtdInfoUserOrig
Expand All @@ -67,6 +69,7 @@ func TestFlashCp(t *testing.T) {
runFlashProcess = runFlashProcessOrig
closeFlashDeviceFile = closeFileOrig
utils.PetWatchdog = PetWatchdogOrig
utils.Sleep = sleepOrig
}()

cases := []struct {
Expand Down Expand Up @@ -168,6 +171,7 @@ func TestFlashCp(t *testing.T) {
}
utils.PetWatchdog = func() {
}
utils.Sleep = func(t time.Duration) {}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
Expand Down Expand Up @@ -227,6 +231,7 @@ func TestRunFlashProcess(t *testing.T) {
flashImageOrig := flashImage
verifyFlashOrig := verifyFlash
PetWatchdogOrig := utils.PetWatchdog
sleepOrig := utils.Sleep
defer func() {
openFlashDeviceFile = openFlashDeviceFileOrig
closeFlashDeviceFile = closeFlashDeviceFileOrig
Expand All @@ -235,6 +240,7 @@ func TestRunFlashProcess(t *testing.T) {
flashImage = flashImageOrig
verifyFlash = verifyFlashOrig
utils.PetWatchdog = PetWatchdogOrig
utils.Sleep = sleepOrig
}()

cases := []struct {
Expand Down Expand Up @@ -298,6 +304,7 @@ func TestRunFlashProcess(t *testing.T) {
}
utils.PetWatchdog = func() {
}
utils.Sleep = func(t time.Duration) {}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
Expand Down Expand Up @@ -441,8 +448,10 @@ func TestHealthCheck(t *testing.T) {

func TestEraseFlashDevice(t *testing.T) {
IOCTLOrig := IOCTL
sleepOrig := utils.Sleep
defer func() {
IOCTL = IOCTLOrig
utils.Sleep = sleepOrig
}()

imData := []byte("foobar")
Expand Down Expand Up @@ -529,6 +538,7 @@ func TestEraseFlashDevice(t *testing.T) {
fileutils.Munmap = func(data []byte) error {
return nil
}
utils.Sleep = func(t time.Duration) {}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
Expand Down Expand Up @@ -566,8 +576,10 @@ func TestEraseFlashDevice(t *testing.T) {

func TestFlashImage(t *testing.T) {
pwriteOrig := fileutils.Pwrite
sleepOrig := utils.Sleep
defer func() {
fileutils.Pwrite = pwriteOrig
utils.Sleep = sleepOrig
}()

imData := []byte("foobar")
Expand Down Expand Up @@ -610,6 +622,9 @@ func TestFlashImage(t *testing.T) {
want: errors.Errorf("roOffset (100) >= file size (6)"),
},
}

utils.Sleep = func(t time.Duration) {}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
fileutils.Pwrite = func(fd int, p []byte, roOffset int64) (n int, err error) {
Expand Down Expand Up @@ -642,13 +657,16 @@ func TestFlashImage(t *testing.T) {
func TestVerifyFlash(t *testing.T) {
mmapFileRangeOrig := fileutils.MmapFileRange
munmapOrig := fileutils.Munmap
sleepOrig := utils.Sleep
defer func() {
fileutils.MmapFileRange = mmapFileRangeOrig
fileutils.Munmap = munmapOrig
utils.Sleep = sleepOrig
}()
fileutils.Munmap = func(b []byte) error {
return nil
}
utils.Sleep = func(t time.Duration) {}

imData := []byte("foobar")
imFile := imageFile{
Expand Down

0 comments on commit 5074d45

Please sign in to comment.