diff --git a/ironic/tests/unit/drivers/modules/ibmc/test_power.py b/ironic/tests/unit/drivers/modules/ibmc/test_power.py
index b0843022ed..51dfce806e 100644
--- a/ironic/tests/unit/drivers/modules/ibmc/test_power.py
+++ b/ironic/tests/unit/drivers/modules/ibmc/test_power.py
@@ -27,7 +27,8 @@ ibmc_client = importutils.try_import('ibmc_client')
 ibmc_error = importutils.try_import('ibmc_client.exceptions')
 
 
-@mock.patch('eventlet.greenthread.sleep', lambda _t: None)
+@mock.patch('oslo_utils.eventletutils.EventletEvent.wait',
+            lambda *args, **kwargs: None)
 class IBMCPowerTestCase(base.IBMCTestCase):
 
     def test_get_properties(self):
@@ -183,7 +184,8 @@ class IBMCPowerTestCase(base.IBMCTestCase):
                              sorted(supported_power_states))
 
 
-@mock.patch('eventlet.greenthread.sleep', lambda _t: None)
+@mock.patch('oslo_utils.eventletutils.EventletEvent.wait',
+            lambda *args, **kwargs: None)
 class IBMCPowerRebootTestCase(base.IBMCTestCase):
 
     @mock.patch.object(ibmc_client, 'connect', autospec=True)
diff --git a/ironic/tests/unit/drivers/modules/ibmc/test_vendor.py b/ironic/tests/unit/drivers/modules/ibmc/test_vendor.py
index 3a316e0d8f..f4e6e99d39 100644
--- a/ironic/tests/unit/drivers/modules/ibmc/test_vendor.py
+++ b/ironic/tests/unit/drivers/modules/ibmc/test_vendor.py
@@ -22,7 +22,8 @@ from ironic.tests.unit.drivers.modules.ibmc import base
 ibmc_client = importutils.try_import('ibmc_client')
 
 
-@mock.patch('eventlet.greenthread.sleep', lambda _t: None)
+@mock.patch('oslo_utils.eventletutils.EventletEvent.wait',
+            lambda *args, **kwargs: None)
 class IBMCVendorTestCase(base.IBMCTestCase):
 
     def setUp(self):
diff --git a/ironic/tests/unit/drivers/modules/irmc/test_power.py b/ironic/tests/unit/drivers/modules/irmc/test_power.py
index 66dbb4e660..dfc112c8c1 100644
--- a/ironic/tests/unit/drivers/modules/irmc/test_power.py
+++ b/ironic/tests/unit/drivers/modules/irmc/test_power.py
@@ -50,7 +50,8 @@ class IRMCPowerInternalMethodsTestCase(test_common.BaseIRMCTest):
         self.assertFalse(irmc_power._is_expected_power_state(
             target_state, boot_status_value))
 
-    @mock.patch('eventlet.greenthread.sleep', lambda n: None)
+    @mock.patch('oslo_utils.eventletutils.EventletEvent.wait',
+                lambda *args, **kwargs: None)
     @mock.patch('ironic.drivers.modules.irmc.power.snmp.SNMPClient',
                 spec_set=True, autospec=True)
     def test__wait_power_state_soft_power_off(self, snmpclient_mock):
@@ -69,7 +70,8 @@ class IRMCPowerInternalMethodsTestCase(test_common.BaseIRMCTest):
             self.assertEqual(states.POWER_OFF, task.node.power_state)
             self.assertEqual(states.NOSTATE, task.node.target_power_state)
 
-    @mock.patch('eventlet.greenthread.sleep', lambda n: None)
+    @mock.patch('oslo_utils.eventletutils.EventletEvent.wait',
+                lambda *args, **kwargs: None)
     @mock.patch('ironic.drivers.modules.irmc.power.snmp.SNMPClient',
                 spec_set=True, autospec=True)
     def test__wait_power_state_soft_reboot(self, snmpclient_mock):
@@ -88,7 +90,8 @@ class IRMCPowerInternalMethodsTestCase(test_common.BaseIRMCTest):
             self.assertEqual(states.POWER_ON, task.node.power_state)
             self.assertEqual(states.NOSTATE, task.node.target_power_state)
 
-    @mock.patch('eventlet.greenthread.sleep', lambda n: None)
+    @mock.patch('oslo_utils.eventletutils.EventletEvent.wait',
+                lambda *args, **kwargs: None)
     @mock.patch('ironic.drivers.modules.irmc.power.snmp.SNMPClient',
                 spec_set=True, autospec=True)
     def test__wait_power_state_timeout(self, snmpclient_mock):
diff --git a/ironic/tests/unit/drivers/modules/redfish/test_bios.py b/ironic/tests/unit/drivers/modules/redfish/test_bios.py
index 98c2aa149d..0dc770c7c1 100644
--- a/ironic/tests/unit/drivers/modules/redfish/test_bios.py
+++ b/ironic/tests/unit/drivers/modules/redfish/test_bios.py
@@ -42,7 +42,8 @@ class NoBiosSystem(object):
                                                      resource=self)
 
 
-@mock.patch('eventlet.greenthread.sleep', lambda _t: None)
+@mock.patch('oslo_utils.eventletutils.EventletEvent.wait',
+            lambda *args, **kwargs: None)
 class RedfishBiosTestCase(db_base.DbTestCase):
 
     def setUp(self):
diff --git a/ironic/tests/unit/drivers/modules/redfish/test_boot.py b/ironic/tests/unit/drivers/modules/redfish/test_boot.py
index 44d337c1ae..f9bad3a04a 100644
--- a/ironic/tests/unit/drivers/modules/redfish/test_boot.py
+++ b/ironic/tests/unit/drivers/modules/redfish/test_boot.py
@@ -36,7 +36,8 @@ sushy = importutils.try_import('sushy')
 INFO_DICT = db_utils.get_test_redfish_info()
 
 
-@mock.patch('eventlet.greenthread.sleep', lambda _t: None)
+@mock.patch('oslo_utils.eventletutils.EventletEvent.wait',
+            lambda *args, **kwargs: None)
 class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
 
     def setUp(self):
diff --git a/ironic/tests/unit/drivers/modules/redfish/test_power.py b/ironic/tests/unit/drivers/modules/redfish/test_power.py
index b84833acfd..09068df24b 100644
--- a/ironic/tests/unit/drivers/modules/redfish/test_power.py
+++ b/ironic/tests/unit/drivers/modules/redfish/test_power.py
@@ -30,7 +30,8 @@ sushy = importutils.try_import('sushy')
 INFO_DICT = db_utils.get_test_redfish_info()
 
 
-@mock.patch('eventlet.greenthread.sleep', lambda _t: None)
+@mock.patch('oslo_utils.eventletutils.EventletEvent.wait',
+            lambda *args, **kwargs: None)
 class RedfishPowerTestCase(db_base.DbTestCase):
 
     def setUp(self):
diff --git a/ironic/tests/unit/drivers/modules/test_ipmitool.py b/ironic/tests/unit/drivers/modules/test_ipmitool.py
index b540a34257..c27e070a3d 100644
--- a/ironic/tests/unit/drivers/modules/test_ipmitool.py
+++ b/ironic/tests/unit/drivers/modules/test_ipmitool.py
@@ -1348,7 +1348,7 @@ class IPMIToolPrivateMethodTestCase(Base):
                                           kill_on_timeout=True)
 
     @mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
-    @mock.patch('eventlet.greenthread.sleep', autospec=True)
+    @mock.patch('oslo_utils.eventletutils.EventletEvent.wait', autospec=True)
     def test__power_on_max_retries(self, sleep_mock, mock_exec):
         self.config(command_retry_timeout=2, group='ipmi')
 
@@ -1370,7 +1370,7 @@ class IPMIToolPrivateMethodTestCase(Base):
         self.assertEqual(expected, mock_exec.call_args_list)
 
     @mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
-    @mock.patch('eventlet.greenthread.sleep', autospec=True)
+    @mock.patch('oslo_utils.eventletutils.EventletEvent.wait', autospec=True)
     def test__soft_power_off(self, sleep_mock, mock_exec):
 
         def side_effect(driver_info, command, **kwargs):
@@ -1390,7 +1390,7 @@ class IPMIToolPrivateMethodTestCase(Base):
         self.assertEqual(states.POWER_OFF, state)
 
     @mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
-    @mock.patch('eventlet.greenthread.sleep', autospec=True)
+    @mock.patch('oslo_utils.eventletutils.EventletEvent.wait', autospec=True)
     def test__soft_power_off_max_retries(self, sleep_mock, mock_exec):
 
         def side_effect(driver_info, command, **kwargs):
@@ -1412,7 +1412,7 @@ class IPMIToolPrivateMethodTestCase(Base):
 
     @mock.patch.object(ipmi, '_power_status', autospec=True)
     @mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
-    @mock.patch('eventlet.greenthread.sleep', autospec=True)
+    @mock.patch('oslo_utils.eventletutils.EventletEvent.wait', autospec=True)
     def test___set_and_wait_no_needless_status_polling(
             self, sleep_mock, mock_exec, mock_status):
         # Check that if the call to power state change fails, it doesn't
diff --git a/ironic/tests/unit/drivers/modules/test_snmp.py b/ironic/tests/unit/drivers/modules/test_snmp.py
index 9702992d2a..5563cfe916 100644
--- a/ironic/tests/unit/drivers/modules/test_snmp.py
+++ b/ironic/tests/unit/drivers/modules/test_snmp.py
@@ -747,7 +747,7 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase):
         mock_client.get.assert_called_once_with(driver._snmp_oid())
         self.assertEqual(states.POWER_OFF, pstate)
 
-    @mock.patch("eventlet.greenthread.sleep", autospec=True)
+    @mock.patch("oslo_utils.eventletutils.EventletEvent.wait", autospec=True)
     def test_power_on_delay(self, mock_sleep, mock_get_client):
         # Ensure driver waits for the state to change following a power on
         mock_client = mock_get_client.return_value
@@ -761,7 +761,7 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase):
         mock_client.get.assert_has_calls(calls)
         self.assertEqual(states.POWER_ON, pstate)
 
-    @mock.patch("eventlet.greenthread.sleep", autospec=True)
+    @mock.patch("oslo_utils.eventletutils.EventletEvent.wait", autospec=True)
     def test_power_off_delay(self, mock_sleep, mock_get_client):
         # Ensure driver waits for the state to change following a power off
         mock_client = mock_get_client.return_value
@@ -775,7 +775,7 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase):
         mock_client.get.assert_has_calls(calls)
         self.assertEqual(states.POWER_OFF, pstate)
 
-    @mock.patch("eventlet.greenthread.sleep", autospec=True)
+    @mock.patch("oslo_utils.eventletutils.EventletEvent.wait", autospec=True)
     def test_power_on_invalid_state(self, mock_sleep, mock_get_client):
         # Ensure driver retries when querying unexpected states following a
         # power on
@@ -790,7 +790,7 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase):
         mock_client.get.assert_has_calls(calls)
         self.assertEqual(states.ERROR, pstate)
 
-    @mock.patch("eventlet.greenthread.sleep", autospec=True)
+    @mock.patch("oslo_utils.eventletutils.EventletEvent.wait", autospec=True)
     def test_power_off_invalid_state(self, mock_sleep, mock_get_client):
         # Ensure driver retries when querying unexpected states following a
         # power off
@@ -851,7 +851,7 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase):
                                                 driver.value_power_off)
         mock_client.get.assert_called_once_with(driver._snmp_oid())
 
-    @mock.patch("eventlet.greenthread.sleep", autospec=True)
+    @mock.patch("oslo_utils.eventletutils.EventletEvent.wait", autospec=True)
     def test_power_on_timeout(self, mock_sleep, mock_get_client):
         # Ensure that a power on consistency poll timeout causes an error
         mock_client = mock_get_client.return_value
@@ -865,7 +865,7 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase):
         mock_client.get.assert_has_calls(calls)
         self.assertEqual(states.ERROR, pstate)
 
-    @mock.patch("eventlet.greenthread.sleep", autospec=True)
+    @mock.patch("oslo_utils.eventletutils.EventletEvent.wait", autospec=True)
     def test_power_off_timeout(self, mock_sleep, mock_get_client):
         # Ensure that a power off consistency poll timeout causes an error
         mock_client = mock_get_client.return_value
@@ -894,7 +894,7 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase):
         mock_client.get.assert_has_calls(calls)
         self.assertEqual(states.POWER_ON, pstate)
 
-    @mock.patch("eventlet.greenthread.sleep", autospec=True)
+    @mock.patch("oslo_utils.eventletutils.EventletEvent.wait", autospec=True)
     def test_power_reset_off_delay(self, mock_sleep, mock_get_client):
         # Ensure driver waits for the power off state change following a power
         # reset
@@ -911,7 +911,7 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase):
         mock_client.get.assert_has_calls(calls)
         self.assertEqual(states.POWER_ON, pstate)
 
-    @mock.patch("eventlet.greenthread.sleep", autospec=True)
+    @mock.patch("oslo_utils.eventletutils.EventletEvent.wait", autospec=True)
     def test_power_reset_on_delay(self, mock_sleep, mock_get_client):
         # Ensure driver waits for the power on state change following a power
         # reset
@@ -928,7 +928,7 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase):
         mock_client.get.assert_has_calls(calls)
         self.assertEqual(states.POWER_ON, pstate)
 
-    @mock.patch("eventlet.greenthread.sleep", autospec=True)
+    @mock.patch("oslo_utils.eventletutils.EventletEvent.wait", autospec=True)
     def test_power_reset_off_delay_on_delay(self, mock_sleep, mock_get_client):
         # Ensure driver waits for both state changes following a power reset
         mock_client = mock_get_client.return_value
@@ -945,7 +945,7 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase):
         mock_client.get.assert_has_calls(calls)
         self.assertEqual(states.POWER_ON, pstate)
 
-    @mock.patch("eventlet.greenthread.sleep", autospec=True)
+    @mock.patch("oslo_utils.eventletutils.EventletEvent.wait", autospec=True)
     def test_power_reset_off_invalid_state(self, mock_sleep, mock_get_client):
         # Ensure driver retries when querying unexpected states following a
         # power off during a reset
@@ -960,7 +960,7 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase):
         mock_client.get.assert_has_calls(calls)
         self.assertEqual(states.ERROR, pstate)
 
-    @mock.patch("eventlet.greenthread.sleep", autospec=True)
+    @mock.patch("oslo_utils.eventletutils.EventletEvent.wait", autospec=True)
     def test_power_reset_on_invalid_state(self, mock_sleep, mock_get_client):
         # Ensure driver retries when querying unexpected states following a
         # power on during a reset
@@ -977,7 +977,7 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase):
         mock_client.get.assert_has_calls(calls)
         self.assertEqual(states.ERROR, pstate)
 
-    @mock.patch("eventlet.greenthread.sleep", autospec=True)
+    @mock.patch("oslo_utils.eventletutils.EventletEvent.wait", autospec=True)
     def test_power_reset_off_timeout(self, mock_sleep, mock_get_client):
         # Ensure that a power off consistency poll timeout during a reset
         # causes an error
@@ -992,7 +992,7 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase):
         mock_client.get.assert_has_calls(calls)
         self.assertEqual(states.ERROR, pstate)
 
-    @mock.patch("eventlet.greenthread.sleep", autospec=True)
+    @mock.patch("oslo_utils.eventletutils.EventletEvent.wait", autospec=True)
     def test_power_reset_on_timeout(self, mock_sleep, mock_get_client):
         # Ensure that a power on consistency poll timeout during a reset
         # causes an error
diff --git a/lower-constraints.txt b/lower-constraints.txt
index 8d1909027d..ef8bc5889a 100644
--- a/lower-constraints.txt
+++ b/lower-constraints.txt
@@ -37,7 +37,7 @@ oslo.rootwrap==5.8.0
 oslo.serialization==2.18.0
 oslo.service==1.24.0
 oslo.upgradecheck==0.1.0
-oslo.utils==3.33.0
+oslo.utils==3.38.0
 oslo.versionedobjects==1.31.2
 oslotest==3.2.0
 osprofiler==1.5.0
diff --git a/requirements.txt b/requirements.txt
index 76ba55b92c..d337ce44d8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -29,7 +29,7 @@ oslo.reports>=1.18.0 # Apache-2.0
 oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0
 oslo.service!=1.28.1,>=1.24.0 # Apache-2.0
 oslo.upgradecheck>=0.1.0 # Apache-2.0
-oslo.utils>=3.33.0 # Apache-2.0
+oslo.utils>=3.38.0 # Apache-2.0
 osprofiler>=1.5.0 # Apache-2.0
 os-traits>=0.4.0 # Apache-2.0
 pecan!=1.0.2,!=1.0.3,!=1.0.4,!=1.2,>=1.0.0 # BSD