Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fall back to slower stat filesize if optimized filesize fails #55641

Merged

Conversation

IanButterworth
Copy link
Sponsor Member

@IanButterworth IanButterworth commented Aug 30, 2024

Based on the triage suggestion #54203 (comment)

@IanButterworth IanButterworth added backport 1.10 Change should be backported to the 1.10 release backport 1.11 Change should be backported to release-1.11 labels Aug 30, 2024
@IanButterworth IanButterworth added the needs tests Unit tests are required for this change label Aug 30, 2024
@giordano
Copy link
Contributor

@ronisbr would you be able to test this?

base/iostream.jl Outdated Show resolved Hide resolved
Co-authored-by: Jameson Nash <vtjnash@gmail.com>
@ronisbr
Copy link
Sponsor Member

ronisbr commented Sep 2, 2024

@ronisbr would you be able to test this?

I will try this weekend! I am currently without access to a Raspberry Pi to test.

@JakeZw

Can you test this PR?

@JakeZw
Copy link

JakeZw commented Sep 3, 2024 via email

@giordano
Copy link
Contributor

giordano commented Sep 3, 2024

Go to the build page, select the build aarch64-Linux-gnu job, open the Artifacts tab, and download the tarball. Open it and you'll have the Julia build on your disk. Maybe there's a way to access the build with juliaup, but I'm not up to date with that.

@KristofferC
Copy link
Sponsor Member

Or copy paste the new function in a @eval Base block.

@JakeZw
Copy link

JakeZw commented Sep 3, 2024

I used giordano's method.

The command that has been causing problems in BaremetalPi is gpio_init(), in which the following commands are executed and then stored in a structure.

        using Mmap
        gpiomem_io  = open("/dev/gpiomem", "w+");
        gpiomem_map = Mmap.mmap(
            gpiomem_io,
            Vector{UInt32},
            (1024,),
            0,
            grow = false
        );

With Julia 1.10.0 it all works.

On the development version that I just downloaded
I get the following output

julia> gpiomem_map = Mmap.mmap(
           gpiomem_io,
           Vector{UInt32},
           (1024,),
           0,
           grow = false
       );
ERROR: ArgumentError: requested size 4096 larger than file size 0, but requested not to grow
Stacktrace:
 [1] mmap(io::IOStream, ::Type{Vector{UInt32}}, dims::Tuple{Int64}, offset::Int64; grow::Bool, shared::Bool)
   @ Mmap ~/Downloads/julia-984f884dfe/share/julia/stdlib/v1.12/Mmap/src/Mmap.jl:226
 [2] top-level scope
   @ REPL[22]:1

Awaiting instructions.

@JakeZw
Copy link

JakeZw commented Sep 3, 2024

Or copy paste the new function in a @eval Base block.

This is a bit cryptic for me.

@IanButterworth
Copy link
Sponsor Member Author

Seems like you need to set grow = true?

@JakeZw
Copy link

JakeZw commented Sep 3, 2024

Still not working

julia> gpiomem_map = Mmap.mmap(
           gpiomem_io,
           Vector{UInt32},
           (1024,),
           0,
           grow = true
       );
ERROR: SystemError: ftruncate: Invalid argument
Stacktrace:
 [1] systemerror(p::Symbol, errno::Int32; extrainfo::Nothing)
   @ Base ./error.jl:185
 [2] systemerror
   @ ./error.jl:184 [inlined]
 [3] grow!(io::IOStream, offset::Int64, len::Int64)
   @ Mmap ~/Downloads/julia-984f884dfe/share/julia/stdlib/v1.12/Mmap/src/Mmap.jl:91
 [4] mmap(io::IOStream, ::Type{Vector{UInt32}}, dims::Tuple{Int64}, offset::Int64; grow::Bool, shared::Bool)
   @ Mmap ~/Downloads/julia-984f884dfe/share/julia/stdlib/v1.12/Mmap/src/Mmap.jl:224
 [5] top-level scope
   @ REPL[24]:1

julia>

@JakeZw
Copy link

JakeZw commented Sep 3, 2024

I don't think filesize() is the source of the BaremetalPi problem. I compared the working and not working versions of the function filesize and they don't correspond to when the problem occurs. See the comments below for what is working and what is not working. I also took at look Mmap.map and it has changed from 1.10.0 to 1.10.1 and is different again for 1.12.0. I will report back to the BaremetalPi issue tracker.


# version 1.10.0  BaremetalPi works
function filesize(s::IOStream)
sz = @_lock_ios s ccall(:ios_filesize, Int64, (Ptr{Cvoid},), s.ios)
if sz == -1
err = Libc.errno()
throw(IOError(string("filesize: ", Libc.strerror(err), " for ", s.name), err))
end
return sz
end

version 1.10.5 BaremetalPi does not work
function filesize(s::IOStream)
sz = @_lock_ios s ccall(:ios_filesize, Int64, (Ptr{Cvoid},), s.ios)
if sz == -1
err = Libc.errno()
throw(IOError(string("filesize: ", Libc.strerror(err), " for ", s.name), err))
end
return sz
end

# version 1.12.0 BaremetalPi does not work
function filesize(s::IOStream)
sz = @_lock_ios s ccall(:ios_filesize, Int64, (Ptr{Cvoid},), s.ios)
if sz == -1
# if `s` is not seekable `ios_filesize` can fail, so fall back to slower stat method
sz = filesize(stat(s))
end
return sz
end

@ronisbr
Copy link
Sponsor Member

ronisbr commented Sep 3, 2024

The problem is the filesize function. There was a modification in Mmap.mmap and it now calls the function filesize (which was not being called before) that leads to the problem in raspberry pi due to the file /dev/gpiomem.

@JakeZw
Copy link

JakeZw commented Sep 4, 2024

Filesize(io) returns 0 with this patch so it is working.

I see what you mean about Mmap,mmap having been changed from 1.10.0 to 1.10.1. This may have introduced another problem?

@vtjnash
Copy link
Sponsor Member

vtjnash commented Sep 4, 2024

I think we just need a check for isfile(t) on the stat result before using the result of the filesize, if the result is 0, since that filters out non-regular files, since we know that will fail the ftruncate syscall, but also won't be useful to call:

  EINVAL fd does not reference a regular file or a POSIX shared memory object.

@vtjnash
Copy link
Sponsor Member

vtjnash commented Sep 4, 2024

(in addition to this PR or after this PR)

@JakeZw
Copy link

JakeZw commented Sep 4, 2024

It is failing on line 91 of grow! in the Mmap.jl file where the systemcall on line 90 returns failure = -1. Complete error message shown above.

@IanButterworth
Copy link
Sponsor Member Author

@vtjnash I gave that a go here. Could be separated into another PR, but for testing purposes here for now.

I couldn't see a tidy way to reuse the stat call within filesize

…the ftruncate syscall

Co-Authored-By: Jameson Nash <vtjnash+github@gmail.com>
@JakeZw
Copy link

JakeZw commented Sep 4, 2024

if I change your line to

filelen == 0 && !isfile(io) && return  # note the ! before isfile

I no longer get an error. I am in process of testing this with BaremetalPi.

It seems that @ronisbr prevented Mmap from using grow! by setting the option grow=false when mmap was called. With the current proposed fix I need to set grow=true, but then grow! returns before performing any function, which seems counterintuitive. I am wondering if the following logic in mmap (lines 220 to 231) should be reviewed and the case of !isfile(io) with grow=false included in the logic there?

    @static if Sys.isunix()
        prot, flags, iswrite = settings(file_desc, shared)
        if requestedSizeLarger
            if iswrite
                if grow
                    grow!(io, offset, len)
                else
                    throw(ArgumentError("requested size $szfile larger than file size $(filesize(io)), but requested not to grow"))
                end
            else
                throw(ArgumentError("unable to increase file size to $szfile due to read-only permissions"))
            end
        end

@ronisbr
Copy link
Sponsor Member

ronisbr commented Sep 4, 2024

It seems that @ronisbr prevented Mmap from using grow! by setting the option grow=false when mmap was called. With the current proposed fix I need to set grow=true, but then grow! returns before performing any function, which seems counterintuitive. I am wondering if the following logic in mmap (lines 220 to 231) should be reviewed and the case of !isfile(io) included in the logic there?

Yes, I agree. However, I can change BaremetalPi.jl to use grow = true if required. It is just that technically you do not need to grow that file.

@JakeZw
Copy link

JakeZw commented Sep 4, 2024

With the fix shown two posts up and a dev version of BaremetalPi with grow set to true, my application that uses BaremetalPi is working.

@oscardssmith
Copy link
Member

oscardssmith commented Sep 21, 2024

by "needs a test", Ian means it needs a test in CI, but it's somewhat unclear how we can do that. IMO since this is a bugfix we should merge without a test if we don't have one.

@IanButterworth
Copy link
Sponsor Member Author

I was imagining that we could either use some address on a linux system to mimic the gpio output, or mock it.
If that isn't easy then I guess merge without tests, but open an issue to note that it's untested?

@JakeZw
Copy link

JakeZw commented Sep 21, 2024

From https://github.com/ronisbr/BaremetalPi.jl/blob/master/src/gpio.jl

the commands that errored are:

  gpiomem_io  = open("/dev/gpiomem", "w+")
  gpiomem_map = Mmap.mmap(
            gpiomem_io,
            Vector{UInt32},
            (GPIOMEM_SIZE,),
            0,
            grow = false
        )

If we change grow = true the proposed changes work.

If we leave grow = false then we need the additional change on line 222 that I proposed above.

This code segment should work as a test.

@ronisbr
Copy link
Sponsor Member

ronisbr commented Sep 21, 2024

The problem is that this scenario only works in a Raspberry Pi, which cannot be emulated by CI here in GitHub.

Copy link
Sponsor Member Author

@IanButterworth IanButterworth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given there are ongoing questions here about what is needed to fix Mmap, I will reduce this to just the issue in the title so it can be merged, then another PR opened to fix the remaining issues.

stdlib/Mmap/src/Mmap.jl Outdated Show resolved Hide resolved
@IanButterworth
Copy link
Sponsor Member Author

Also, seems we don't have a good idea for a test here, so I'll remove that needs label.

@IanButterworth IanButterworth added merge me PR is reviewed. Merge when all tests are passing and removed needs tests Unit tests are required for this change labels Sep 23, 2024
@ronisbr
Copy link
Sponsor Member

ronisbr commented Sep 23, 2024

Hi @IanButterworth

Given there are ongoing questions here about what is needed to fix Mmap, I will reduce this to just the issue in the title so it can be merged, then another PR opened to fix the remaining issues.

Is it really necessary? I thought everything was fine with that suggestion. The current state does not fix #54203. Since this is an important regression (nobody is able to use Julia in the current state to access Raspberry Pi's GPIO), can't we try to implement the solution to #54203 in this PR to fix the problem faster?

@ronisbr
Copy link
Sponsor Member

ronisbr commented Sep 23, 2024

By the way, the problem is that this PR:

https://github.com/JuliaLang/julia/pull/44354/files

now perform checks that were not performed before (like throwing an error in some conditions).

@IanButterworth
Copy link
Sponsor Member Author

The Mmap fixes have been opened here #55849

@JakeZw opening PRs isn't as complicated as the guide at #55641 (comment) makes out.

@ronisbr there's just been a lot of noise in this PR and the title fix should get in. See #55849 for the remainder. Please review & approve that if it is correct.

@ronisbr
Copy link
Sponsor Member

ronisbr commented Sep 23, 2024

@ronisbr there's just been a lot of noise in this PR and the title fix should get in. See #55849 for the remainder. Please review & approve that if it is correct.

Perfect @IanButterworth ! You were very fast :) I just tested both modifications and, from my side, everything is working perfectly (Raspberry Pi Zero 2). However, I think it will be important if @JakeZw test it too.

@IanButterworth IanButterworth merged commit fc9f147 into JuliaLang:master Sep 23, 2024
8 of 10 checks passed
IanButterworth added a commit to IanButterworth/julia that referenced this pull request Sep 24, 2024
KristofferC pushed a commit that referenced this pull request Sep 24, 2024
@KristofferC KristofferC mentioned this pull request Sep 24, 2024
30 tasks
vtjnash added a commit that referenced this pull request Sep 24, 2024
Enables the fix for #28245 in #44354 for Apple now that the Julia bug is
fixed by #55641.

Closes #28245
@giordano giordano removed the merge me PR is reviewed. Merge when all tests are passing label Sep 24, 2024
IanButterworth added a commit that referenced this pull request Sep 24, 2024
Fixes #54203
Requires #55641

Based on
#55641 (comment)
cc. @JakeZw @ronisbr

---------

Co-authored-by: Jameson Nash <vtjnash@gmail.com>
KristofferC added a commit that referenced this pull request Sep 25, 2024
Backported PRs:
- [x] #55773 <!-- Add compat entry for `Base.donotdelete` -->
- [x] #41244 <!-- Fix shell `cd` error when working dir has been deleted
-->
- [x] #55795 <!-- fix #52986, regression in `@doc` of macro without REPL
loaded -->
- [x] #55829 <!-- [Dates] Make test more robust against non-UTC
timezones -->
- [x] #55641 <!-- fall back to slower stat filesize if optimized
filesize fails -->
- [x] #55744 <!-- fix #45494, error in ssa conversion with complex type
decl -->
- [x] #55783 <!-- use `inferencebarrier` instead of `invokelatest` for
1-arg `@assert` -->
- [x] #55739 <!-- Add `invokelatest` barrier to `string(...)` in
`@assert` -->

Need manual backport:
- [ ] #55798 <!-- Broadcast binary ops involving strided triangular -->

Contains multiple commits, manual intervention needed:
- [ ] #55509 <!-- Fix cong implementation to be properly random and not
just cycling. -->
- [ ] #55569 <!-- Add a docs section about loading/precomp/ttfx time
tuning -->
- [ ] #55824 <!-- Replace regex package module checks with actual code
checks -->

Non-merged PRs with backport label:
- [ ] #55845 <!-- privatize annotated string API, take two -->
- [ ] #55828 <!-- Fix some corner cases of `isapprox` with unsigned
integers -->
- [ ] #55813 <!-- Check for conflicting `@ccallable` name before JIT
registration -->
- [ ] #55743 <!-- doc: heap snapshot viewing -->
- [ ] #55741 <!-- Change annotations to use a NamedTuple -->
- [ ] #55534 <!-- Set stdlib sources as read-only during installation
-->
- [ ] #55499 <!-- propagate the terminal's `displaysize` to the
`IOContext` used by the REPL -->
- [ ] #55458 <!-- Allow for generically extracting unannotated string
-->
- [ ] #55457 <!-- Make AnnotateChar equality consider annotations -->
- [ ] #55453 <!-- Privatise the annotations API, for StyledStrings -->
- [ ] #55355 <!-- relocation: account for trailing path separator in
depot paths -->
- [ ] #55220 <!-- `isfile_casesensitive` fixes on Windows -->
- [ ] #55169 <!-- `propertynames` for SVD respects private argument -->
- [ ] #54457 <!-- Make `String(::Memory)` copy -->
- [ ] #53957 <!-- tweak how filtering is done for what packages should
be precompiled -->
- [ ] #51479 <!-- prevent code loading from lookin in the versioned
environment when building Julia -->
- [ ] #50813 <!-- More doctests for Sockets and capitalization fix -->
- [ ] #50157 <!-- improve docs for `@inbounds` and
`Base.@propagate_inbounds` -->
@KristofferC KristofferC removed the backport 1.11 Change should be backported to release-1.11 label Sep 25, 2024
vtjnash added a commit that referenced this pull request Sep 26, 2024
Enables the fix for #28245 in #44354 for Apple now that the Julia bug is
fixed by #55641.

Closes #28245
KristofferC pushed a commit that referenced this pull request Sep 30, 2024
Fixes #54203
Requires #55641

Based on
#55641 (comment)
cc. @JakeZw @ronisbr

---------

Co-authored-by: Jameson Nash <vtjnash@gmail.com>
(cherry picked from commit b0db75d)
vtjnash added a commit that referenced this pull request Oct 1, 2024
Enables the fix for #28245 in #44354 for Apple now that the Julia bug is
fixed by #55641.

Closes #28245
vtjnash added a commit that referenced this pull request Oct 1, 2024
Enables the fix for #28245 in #44354 for Apple now that the Julia bug is
fixed by #55641.

Closes #28245
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport 1.10 Change should be backported to the 1.10 release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants