diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 7de963e3a0a1..a2c7b80e3c6e 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -9478,12 +9478,20 @@ class ComputeManager(manager.Manager): if timeutils.is_older_than(shelved_at, CONF.shelved_offload_time): to_gc.append(instance) + cyclient = cyborg.get_client(context) for instance in to_gc: try: instance.task_state = task_states.SHELVING_OFFLOADING instance.save(expected_task_state=(None,)) - self.shelve_offload_instance(context, instance, - clean_shutdown=False) + accel_uuids = [] + if instance.flavor.extra_specs.get('accel:device_profile'): + # TODO(brinzhang): After cyborg support batch query ARQs + # for more than one instances, we will improve efficiency + # with this implemention. + accel_uuids = cyclient.get_arq_uuids_for_instance(instance) + self.shelve_offload_instance( + context, instance, clean_shutdown=False, + accel_uuids=accel_uuids) except Exception: LOG.exception('Periodic task failed to offload instance.', instance=instance) diff --git a/nova/tests/unit/compute/test_shelve.py b/nova/tests/unit/compute/test_shelve.py index 0df00c463c78..ae85e8026f22 100644 --- a/nova/tests/unit/compute/test_shelve.py +++ b/nova/tests/unit/compute/test_shelve.py @@ -762,6 +762,34 @@ class ShelveComputeManagerTestCase(test_compute.BaseTestCase): self.assertTrue(soi.called) self.assertEqual([instance2.uuid], data) + @mock.patch('nova.accelerator.cyborg._CyborgClient.' + 'get_arq_uuids_for_instance') + @mock.patch('oslo_utils.timeutils.is_older_than') + @mock.patch('oslo_utils.timeutils.parse_strtime') + def test_shelved_poll_with_accel_uuids(self, mock_parse, mock_older, + mock_get_arq_uuids): + self.flags(shelved_offload_time=1) + mock_older.return_value = True + instance = self._create_fake_instance_obj() + instance.task_state = None + instance.vm_state = vm_states.SHELVED + instance.host = self.compute.host + instance.system_metadata = {'shelved_at': ''} + instance.flavor.extra_specs['accel:device_profile'] = 'dp_test' + mock_get_arq_uuids.return_value = [uuids.fake] + instance.save() + + data = [] + + def fake_soi(context, instance, **kwargs): + data.append(instance.uuid) + + with mock.patch.object(self.compute, 'shelve_offload_instance') as soi: + soi.side_effect = fake_soi + self.compute._poll_shelved_instances(self.context) + self.assertTrue(soi.called) + self.assertEqual([instance.uuid], data) + @mock.patch('oslo_utils.timeutils.is_older_than') @mock.patch('oslo_utils.timeutils.parse_strtime') def test_shelved_poll_checks_task_state_on_save(self, mock_parse,