Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions rocfile/src/backend/fastpath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,23 @@
#include <cstdint>
#include <fcntl.h>
#include <hip/hip_runtime_api.h>
#include <linux/stat.h>
#include <stdexcept>

using namespace rocFile;
using namespace std;

/* The fastpath backend is used when:
* - The file has been opened with the O_DIRECT flag
* - file_offset is 4KiB aligned
* - buffer_offset is 4KiB aligned
* - size is a multiple of 4KiB
* - if statx contains direct io information
* - statx indicates the file descriptor supports direct IO (see statx (2))
* - file_offset is a multiple of stx_dio_offset_align (see statx (2))
* - buffer_offset is a multiple of stx_dio_mem_align (see statx (2))
* - size is a multiple of stx_dio_offset_align (see statx (2))
* - if statx does not contain direct io information
* - file_offset is a multiple of 4096
* - buffer_offset is a multiple of 4096
* - size is a multiple of 4096
* - The buffer type is hipMemoryTypeDevice
*
* When using the fastpath the IO flows through the following
Expand Down Expand Up @@ -126,9 +133,18 @@ Fastpath::score(shared_ptr<IFile> file, shared_ptr<IBuffer> buffer, size_t size,
accept_io &= 0 <= file_offset;
accept_io &= 0 <= buffer_offset;

#if defined(STATX_DIOALIGN)
const struct statx &stx{file->getStatx()};
accept_io &= !!(stx.stx_mask & STATX_DIOALIGN);
accept_io &= stx.stx_dio_offset_align && stx.stx_dio_mem_align;
accept_io &= !(size & (stx.stx_dio_offset_align - 1));
accept_io &= !(file_offset & (stx.stx_dio_offset_align - 1));
accept_io &= !(buffer_offset & (stx.stx_dio_mem_align - 1));
#else
accept_io &= !(size & 0xFFF);
accept_io &= !(file_offset & 0xFFF);
accept_io &= !(buffer_offset & 0xFFF);
#endif

return accept_io ? 100 : -1;
}
Expand Down
34 changes: 18 additions & 16 deletions rocfile/src/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <fcntl.h>
#include <iterator>
#include <utility>
#include <sys/sysmacros.h>
#include <vector>

using std::optional;
Expand All @@ -23,8 +24,16 @@ using std::vector;
namespace rocFile {

UnregisteredFile::UnregisteredFile(int fd)
: m_fd(fd), m_stat{Context<Sys>::get()->fstat(fd)}, m_flags{Context<Sys>::get()->fcntl(fd, F_GETFL, 0)},
m_mountinfo{Context<LibMountHelper>::get()->getMountInfo(m_stat.st_dev)}
: m_fd(fd), m_stx{Context<Sys>::get()->statx(fd, "", AT_EMPTY_PATH,
#if defined(STATX_DIOALIGN)
STATX_TYPE | STATX_MODE | STATX_DIOALIGN
#else
STATX_TYPE | STATX_MODE
#endif
)},
m_flags{Context<Sys>::get()->fcntl(fd, F_GETFL, 0)},
m_mountinfo{
Context<LibMountHelper>::get()->getMountInfo(makedev(m_stx.stx_dev_major, m_stx.stx_dev_minor))}
{
}

Expand All @@ -34,10 +43,10 @@ UnregisteredFile::getFd() const noexcept
return m_fd;
}

struct stat
UnregisteredFile::getStat() const noexcept
struct statx
UnregisteredFile::getStatx() const noexcept
{
return m_stat;
return m_stx;
}

int
Expand All @@ -59,8 +68,7 @@ IFile::getHandle() const
}

File::File(const UnregisteredFile &uf)
: fd{uf.getFd()}, device{uf.getStat().st_dev}, mode{uf.getStat().st_mode}, status_flags{uf.getFlags()},
mountinfo{uf.getMountInfo()}
: fd{uf.getFd()}, stx{uf.getStatx()}, status_flags{uf.getFlags()}, mountinfo{uf.getMountInfo()}
{
}

Expand All @@ -70,16 +78,10 @@ File::getFd() const
return fd;
}

dev_t
File::getDevice() const
{
return device;
}

mode_t
File::getMode() const
const struct statx &
File::getStatx() const noexcept
{
return mode;
return stx;
}

int
Expand Down
34 changes: 12 additions & 22 deletions rocfile/src/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@
#include "rocfile.h"
#include "mountinfo.h"

#include <linux/stat.h>
#include <memory>
#include <optional>
#include <stdexcept>
#include <sys/stat.h>
#include <sys/types.h>
#include <unordered_map>

namespace rocFile {
Expand Down Expand Up @@ -51,8 +50,8 @@ class UnregisteredFile {
/// @return Returns the file descriptor
int getFd() const noexcept;

/// @return Returns the information provided by fstat (2)
struct stat getStat() const noexcept;
/// @return Returns the information provided by statx (2)
struct statx getStatx() const noexcept;

/// @return Returns the flags provided by fcntl (2)
int getFlags() const noexcept;
Expand All @@ -64,8 +63,8 @@ class UnregisteredFile {
/// @brief The file descriptor
int m_fd;

/// @brief Information provided by fstat (2)
struct stat m_stat;
/// @brief Information provided by statx (2)
struct statx m_stx;

/// @brief Flags provided by fcntl(2)
int m_flags;
Expand All @@ -82,11 +81,10 @@ class IFile {
/// @return The handle for this file
virtual rocFileHandle_t getHandle() const;

virtual int getFd() const = 0;
virtual dev_t getDevice() const = 0;
virtual mode_t getMode() const = 0;
virtual int getStatusFlags() const = 0;
virtual std::optional<MountInfo> getMountInfo() const = 0;
virtual int getFd() const = 0;
virtual const struct statx &getStatx() const noexcept = 0;
virtual int getStatusFlags() const = 0;
virtual std::optional<MountInfo> getMountInfo() const = 0;
};

class File : public IFile {
Expand All @@ -103,8 +101,7 @@ class File : public IFile {
File &operator=(File &&) = delete;

virtual int getFd() const override;
virtual dev_t getDevice() const override;
virtual mode_t getMode() const override;
virtual const struct statx &getStatx() const noexcept override;
virtual int getStatusFlags() const override;
virtual std::optional<MountInfo> getMountInfo() const override;

Expand All @@ -116,15 +113,8 @@ class File : public IFile {
/// @brief The file descriptor
int fd;

/// @brief The ID of the device containing file
///
/// Used to lookup mount information. See fstat(2), inode(7), and proc_pid_mountinfo(5)
dev_t device;

/// @brief The file type and mode
///
/// Specifies the file type (regular file, block device, ...) and mode. See fstat(2) and inode(7)
mode_t mode;
/// @brief File status information obtained from statx (2)
struct statx stx;

/// @brief The file's status flags. See fcntl(2)
///
Expand Down
9 changes: 9 additions & 0 deletions rocfile/src/sys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "sys.h"

#include <bits/statx-generic.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <syslog.h>
Expand Down Expand Up @@ -69,4 +70,12 @@ Sys::fcntl(int fd, int op, uintptr_t arg) const
return throwOn<Sys::RuntimeError>(-1, ::fcntl(fd, op, arg));
}

struct statx
Sys::statx(int dirfd, const char *pathname, int flags, unsigned int mask) const
{
struct statx statxbuf;
throwOn<Sys::RuntimeError>(-1, ::statx(dirfd, pathname, flags, mask, &statxbuf));
return statxbuf;
}

}
5 changes: 3 additions & 2 deletions rocfile/src/sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
#include <cerrno>
#include <cstddef>
#include <cstdint>
#include <linux/stat.h>
#include <stdexcept>

#include <sys/stat.h>
#include <sys/types.h>

Expand All @@ -33,7 +33,8 @@ struct Sys {

virtual void syslog(int priority, const char *msg) const;

virtual struct stat fstat(int fd) const;
virtual struct stat fstat(int fd) const;
virtual struct statx statx(int dirfd, const char *pathname, int flags, unsigned int mask) const;

virtual int fcntl(int fd, int op, uintptr_t arg) const;

Expand Down
2 changes: 1 addition & 1 deletion rocfile/test/driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ TEST_F(RocFileDriverAdmin, HandleRegisterBadFD)
descr.handle.fd = -1;
descr.type = rocFileHandleTypeOpaqueFD;

EXPECT_CALL(msys, fstat).WillOnce(Throw(Sys::RuntimeError(EBADF)));
EXPECT_CALL(msys, statx).WillOnce(Throw(Sys::RuntimeError(EBADF)));

ASSERT_EQ(rocFileUseCount(), 0);
ASSERT_NE(rocFileHandleRegister(&handle, &descr), ROCFILE_SUCCESS);
Expand Down
Loading
Loading