summaryrefslogtreecommitdiff
path: root/storage/innobase/os
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2019-12-09 15:09:41 +0100
committerOleksandr Byelkin <sanja@mariadb.com>2019-12-09 15:09:41 +0100
commita15234bf4bf98d7833996284c033fc53a981f5d4 (patch)
treed989b448854f9d59de5ca16b962414591c8a5b2e /storage/innobase/os
parent9a6212008999da44b136605c1abf2cc9c7cc4b2c (diff)
parente5e5877740f248de848219ee3a1d2881cd5c5b82 (diff)
downloadmariadb-git-a15234bf4bf98d7833996284c033fc53a981f5d4.tar.gz
Merge branch '10.3' into 10.4
Diffstat (limited to 'storage/innobase/os')
-rw-r--r--storage/innobase/os/os0file.cc112
-rw-r--r--storage/innobase/os/os0thread.cc10
2 files changed, 81 insertions, 41 deletions
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index a2243dec9cf..1eb3c4f202d 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -409,7 +409,7 @@ public:
/** Accessor for the AIO context
@param[in] segment Segment for which to get the context
@return the AIO context for the segment */
- io_context* io_ctx(ulint segment)
+ io_context_t io_ctx(ulint segment)
MY_ATTRIBUTE((warn_unused_result))
{
ut_ad(segment < get_n_segments());
@@ -417,11 +417,11 @@ public:
return(m_aio_ctx[segment]);
}
- /** Creates an io_context for native linux AIO.
+ /** Creates an io_context_t for native linux AIO.
@param[in] max_events number of events
@param[out] io_ctx io_ctx to initialize.
@return true on success. */
- static bool linux_create_io_ctx(unsigned max_events, io_context_t* io_ctx)
+ static bool linux_create_io_ctx(unsigned max_events, io_context_t& io_ctx)
MY_ATTRIBUTE((warn_unused_result));
/** Checks if the system supports native linux aio. On some kernel
@@ -618,7 +618,7 @@ private:
/** completion queue for IO. There is one such queue per
segment. Each thread will work on one ctx exclusively. */
- io_context_t* m_aio_ctx;
+ std::vector<io_context_t> m_aio_ctx;
/** The array to collect completed IOs. There is one such
event for each possible pending IO. The size of the array
@@ -1675,10 +1675,14 @@ LinuxAIOHandler::resubmit(Slot* slot)
iocb->data = slot;
+ ut_a(reinterpret_cast<size_t>(iocb->u.c.buf) % OS_FILE_LOG_BLOCK_SIZE
+ == 0);
+
/* Resubmit an I/O request */
int ret = io_submit(m_array->io_ctx(m_segment), 1, &iocb);
+ ut_a(ret != -EINVAL);
- if (ret < -1) {
+ if (ret < 0) {
errno = -ret;
}
@@ -1779,8 +1783,8 @@ LinuxAIOHandler::collect()
ut_ad(m_array != NULL);
ut_ad(m_segment < m_array->get_n_segments());
- /* Which io_context we are going to use. */
- io_context* io_ctx = m_array->io_ctx(m_segment);
+ /* Which io_context_t we are going to use. */
+ io_context_t io_ctx = m_array->io_ctx(m_segment);
/* Starting point of the m_segment we will be working on. */
ulint start_pos = m_segment * m_n_slots;
@@ -1807,6 +1811,8 @@ LinuxAIOHandler::collect()
int ret;
ret = io_getevents(io_ctx, 1, m_n_slots, events, &timeout);
+ ut_a(ret != -EINVAL);
+ ut_ad(ret != -EFAULT);
for (int i = 0; i < ret; ++i) {
@@ -2033,14 +2039,18 @@ AIO::linux_dispatch(Slot* slot)
/* Find out what we are going to work with.
The iocb struct is directly in the slot.
- The io_context is one per segment. */
+ The io_context_t is one per segment. */
ulint io_ctx_index;
struct iocb* iocb = &slot->control;
io_ctx_index = (slot->pos * m_n_segments) / m_slots.size();
- int ret = io_submit(m_aio_ctx[io_ctx_index], 1, &iocb);
+ ut_a(reinterpret_cast<size_t>(iocb->u.c.buf) % OS_FILE_LOG_BLOCK_SIZE
+ == 0);
+
+ int ret = io_submit(io_ctx(io_ctx_index), 1, &iocb);
+ ut_a(ret != -EINVAL);
/* io_submit() returns number of successfully queued requests
or -errno. */
@@ -2052,25 +2062,26 @@ AIO::linux_dispatch(Slot* slot)
return(ret == 1);
}
-/** Creates an io_context for native linux AIO.
+/** Creates an io_context_t for native linux AIO.
@param[in] max_events number of events
@param[out] io_ctx io_ctx to initialize.
@return true on success. */
bool
AIO::linux_create_io_ctx(
unsigned max_events,
- io_context_t* io_ctx)
+ io_context_t& io_ctx)
{
ssize_t n_retries = 0;
for (;;) {
- memset(io_ctx, 0x0, sizeof(*io_ctx));
+ memset(&io_ctx, 0x0, sizeof(io_ctx));
/* Initialize the io_ctx. Tell it how many pending
IO requests this context will handle. */
- int ret = io_setup(max_events, io_ctx);
+ int ret = io_setup(max_events, &io_ctx);
+ ut_a(ret != -EINVAL);
if (ret == 0) {
/* Success. Return now. */
@@ -2149,7 +2160,7 @@ AIO::is_linux_native_aio_supported()
io_context_t io_ctx;
char name[1000];
- if (!linux_create_io_ctx(1, &io_ctx)) {
+ if (!linux_create_io_ctx(1, io_ctx)) {
/* The platform does not support native aio. */
@@ -2165,6 +2176,10 @@ AIO::is_linux_native_aio_supported()
<< "Unable to create temp file to check"
" native AIO support.";
+ int ret = io_destroy(io_ctx);
+ ut_a(ret != -EINVAL);
+ ut_ad(ret != -EFAULT);
+
return(false);
}
} else {
@@ -2194,6 +2209,10 @@ AIO::is_linux_native_aio_supported()
<< " \"" << name << "\" to check native"
<< " AIO read support.";
+ int ret = io_destroy(io_ctx);
+ ut_a(ret != EINVAL);
+ ut_ad(ret != EFAULT);
+
return(false);
}
}
@@ -2222,11 +2241,15 @@ AIO::is_linux_native_aio_supported()
io_prep_pread(p_iocb, fd, ptr, 512, 0);
}
+ ut_a(reinterpret_cast<size_t>(p_iocb->u.c.buf) % OS_FILE_LOG_BLOCK_SIZE
+ == 0);
int err = io_submit(io_ctx, 1, &p_iocb);
+ ut_a(err != -EINVAL);
if (err >= 1) {
/* Now collect the submitted IO request. */
err = io_getevents(io_ctx, 1, 1, &io_event, NULL);
+ ut_a(err != -EINVAL);
}
ut_free(buf);
@@ -2234,7 +2257,13 @@ AIO::is_linux_native_aio_supported()
switch (err) {
case 1:
- return(true);
+ {
+ int ret = io_destroy(io_ctx);
+ ut_a(ret != -EINVAL);
+ ut_ad(ret != -EFAULT);
+
+ return(true);
+ }
case -EINVAL:
case -ENOSYS:
@@ -2254,6 +2283,10 @@ AIO::is_linux_native_aio_supported()
<< "returned error[" << -err << "]";
}
+ int ret = io_destroy(io_ctx);
+ ut_a(ret != -EINVAL);
+ ut_ad(ret != -EFAULT);
+
return(false);
}
@@ -5602,8 +5635,7 @@ AIO::AIO(
m_n_segments(segments),
m_n_reserved()
# ifdef LINUX_NATIVE_AIO
- ,m_aio_ctx(),
- m_events(m_slots.size())
+ ,m_events(m_slots.size())
# endif /* LINUX_NATIVE_AIO */
#ifdef WIN_ASYNC_IO
,m_completion_port(new_completion_port())
@@ -5659,29 +5691,20 @@ AIO::init_slots()
dberr_t
AIO::init_linux_native_aio()
{
- /* Initialize the io_context array. One io_context
- per segment in the array. */
- ut_a(m_aio_ctx == NULL);
-
- m_aio_ctx = static_cast<io_context**>(
- ut_zalloc_nokey(m_n_segments * sizeof(*m_aio_ctx)));
-
- if (m_aio_ctx == NULL) {
- return(DB_OUT_OF_MEMORY);
- }
+ /* Initialize the io_context_t array. One io_context_t
+ per segment in the array. */
+ m_aio_ctx.resize(get_n_segments());
- io_context** ctx = m_aio_ctx;
ulint max_events = slots_per_segment();
- for (ulint i = 0; i < m_n_segments; ++i, ++ctx) {
+ for (std::vector<io_context_t>::iterator it = m_aio_ctx.begin(),
+ end = m_aio_ctx.end();
+ it != end; ++it) {
- if (!linux_create_io_ctx(max_events, ctx)) {
+ if (!linux_create_io_ctx(max_events, *it)) {
/* If something bad happened during aio setup
we disable linux native aio.
- The disadvantage will be a small memory leak
- at shutdown but that's ok compared to a crash
- or a not working server.
This frequently happens when running the test suite
with many threads on a system with low fs.aio-max-nr!
*/
@@ -5693,8 +5716,15 @@ AIO::init_linux_native_aio()
<< "try increasing system "
<< "fs.aio-max-nr to 1048576 or larger or "
<< "setting innodb_use_native_aio = 0 in my.cnf";
- ut_free(m_aio_ctx);
- m_aio_ctx = 0;
+
+ for (std::vector<io_context_t>::iterator it2
+ = m_aio_ctx.begin();
+ it2 != it; ++it2) {
+ int ret = io_destroy(*it2);
+ ut_a(ret != -EINVAL);
+ }
+
+ m_aio_ctx.clear();
srv_use_native_aio = FALSE;
return(DB_SUCCESS);
}
@@ -5770,15 +5800,15 @@ AIO::~AIO()
#if defined(LINUX_NATIVE_AIO)
if (srv_use_native_aio) {
- m_events.clear();
- ut_free(m_aio_ctx);
+ for (ulint i = 0; i < m_aio_ctx.size(); i++) {
+ int ret = io_destroy(m_aio_ctx[i]);
+ ut_a(ret != -EINVAL);
+ }
}
#endif /* LINUX_NATIVE_AIO */
#if defined(WIN_ASYNC_IO)
CloseHandle(m_completion_port);
#endif
-
- m_slots.clear();
}
/** Initializes the asynchronous io system. Creates one array each for ibuf
@@ -6072,6 +6102,10 @@ AIO::reserve_slot(
os_offset_t offset,
ulint len)
{
+ ut_ad(reinterpret_cast<size_t>(buf) % OS_FILE_LOG_BLOCK_SIZE == 0);
+ ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0);
+ ut_ad(len % OS_FILE_LOG_BLOCK_SIZE == 0);
+
#ifdef WIN_ASYNC_IO
ut_a((len & 0xFFFFFFFFUL) == len);
#endif /* WIN_ASYNC_IO */
diff --git a/storage/innobase/os/os0thread.cc b/storage/innobase/os/os0thread.cc
index 6e077d88067..bb5da7df7c4 100644
--- a/storage/innobase/os/os0thread.cc
+++ b/storage/innobase/os/os0thread.cc
@@ -125,11 +125,17 @@ os_thread_create_func(
pthread_attr_t attr;
- pthread_attr_init(&attr);
+ int ret = pthread_attr_init(&attr);
+ if (UNIV_UNLIKELY(ret)) {
+ fprintf(stderr,
+ "InnoDB: Error: pthread_attr_init() returned %d\n",
+ ret);
+ abort();
+ }
os_thread_count++;
- int ret = pthread_create(&new_thread_id, &attr, func, arg);
+ ret = pthread_create(&new_thread_id, &attr, func, arg);
ut_a(ret == 0);