mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-6357: Not able to select GPU card in case of GPU-passthrough.
This commit is contained in:
parent
09f83e48eb
commit
2ae9da8d47
@ -23,10 +23,6 @@ public class GPU {
|
|||||||
pciDevice,
|
pciDevice,
|
||||||
vgpuType
|
vgpuType
|
||||||
}
|
}
|
||||||
public enum Type {
|
|
||||||
GPU_Passthrough,
|
|
||||||
VGPU
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum vGPUType {
|
public enum vGPUType {
|
||||||
GRID_K100("GRID K100"),
|
GRID_K100("GRID K100"),
|
||||||
|
|||||||
@ -151,26 +151,29 @@ public interface ResourceManager extends ResourceService {
|
|||||||
/**
|
/**
|
||||||
* Check if host has GPU devices available
|
* Check if host has GPU devices available
|
||||||
* @param hostId the host to be checked
|
* @param hostId the host to be checked
|
||||||
|
* @param groupName: gpuCard name
|
||||||
* @param vgpuType the VGPU type
|
* @param vgpuType the VGPU type
|
||||||
* @return true when the host has the capacity with given VGPU type
|
* @return true when the host has the capacity with given VGPU type
|
||||||
*/
|
*/
|
||||||
boolean isGPUDeviceAvailable(long hostId, String vgpuType);
|
boolean isGPUDeviceAvailable(long hostId, String groupName, String vgpuType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get available GPU device
|
* Get available GPU device
|
||||||
* @param hostId the host to be checked
|
* @param hostId the host to be checked
|
||||||
|
* @param groupName: gpuCard name
|
||||||
* @param vgpuType the VGPU type
|
* @param vgpuType the VGPU type
|
||||||
* @return GPUDeviceTO[]
|
* @return GPUDeviceTO[]
|
||||||
*/
|
*/
|
||||||
GPUDeviceTO getGPUDevice(long hostId, String vgpuType);
|
GPUDeviceTO getGPUDevice(long hostId, String groupName, String vgpuType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return listof available GPU devices
|
* Return listof available GPU devices
|
||||||
* @param hostId, the host to be checked
|
* @param hostId, the host to be checked
|
||||||
|
* @param groupName: gpuCard name
|
||||||
* @param vgpuType the VGPU type
|
* @param vgpuType the VGPU type
|
||||||
* @return List of HostGpuGroupsVO.
|
* @return List of HostGpuGroupsVO.
|
||||||
*/
|
*/
|
||||||
List<HostGpuGroupsVO> listAvailableGPUDevice(long hostId, String vgpuType);
|
List<HostGpuGroupsVO> listAvailableGPUDevice(long hostId, String groupName, String vgpuType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update GPU device details (post VM deployment)
|
* Update GPU device details (post VM deployment)
|
||||||
|
|||||||
@ -278,10 +278,12 @@ public class FirstFitAllocator extends AdapterBase implements HostAllocator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if GPU device is required by offering and host has the availability
|
// Check if GPU device is required by offering and host has the availability
|
||||||
if ((offeringDetails = _serviceOfferingDetailsDao.findDetail(serviceOfferingId, GPU.Keys.vgpuType.toString())) != null
|
if ((offeringDetails = _serviceOfferingDetailsDao.findDetail(serviceOfferingId, GPU.Keys.vgpuType.toString())) != null) {
|
||||||
&& !_resourceMgr.isGPUDeviceAvailable(host.getId(), offeringDetails.getValue())){
|
ServiceOfferingDetailsVO groupName = _serviceOfferingDetailsDao.findDetail(serviceOfferingId, GPU.Keys.pciDevice.toString());
|
||||||
s_logger.info("Host name: " + host.getName() + ", hostId: "+ host.getId() +" does not have required GPU devices available");
|
if(!_resourceMgr.isGPUDeviceAvailable(host.getId(), groupName.getValue(), offeringDetails.getValue())){
|
||||||
continue;
|
s_logger.info("Host name: " + host.getName() + ", hostId: "+ host.getId() +" does not have required GPU devices available");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cpu_requested = offering.getCpu() * offering.getSpeed();
|
int cpu_requested = offering.getCpu() * offering.getSpeed();
|
||||||
|
|||||||
@ -2084,47 +2084,33 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
offering.setHypervisorSnapshotReserve(hypervisorSnapshotReserve);
|
offering.setHypervisorSnapshotReserve(hypervisorSnapshotReserve);
|
||||||
|
|
||||||
List<ServiceOfferingDetailsVO> detailsVO = null;
|
List<ServiceOfferingDetailsVO> detailsVO = null;
|
||||||
if (details != null) {
|
if (details != null) {
|
||||||
// Check if the user has passed the gpu-type before passing the VGPU type
|
// Check if the user has passed the gpu-type before passing the VGPU type
|
||||||
if (!details.containsKey(GPU.Keys.pciDevice.toString()) && details.containsKey(GPU.Keys.vgpuType.toString())) {
|
if (!details.containsKey(GPU.Keys.pciDevice.toString()) || !details.containsKey(GPU.Keys.vgpuType.toString())) {
|
||||||
throw new InvalidParameterValueException("Please specify the gpu type");
|
throw new InvalidParameterValueException("Please specify the pciDevice and vgpuType correctly.");
|
||||||
}
|
}
|
||||||
detailsVO = new ArrayList<ServiceOfferingDetailsVO>();
|
detailsVO = new ArrayList<ServiceOfferingDetailsVO>();
|
||||||
for (Entry<String, String> detailEntry : details.entrySet()) {
|
for (Entry<String, String> detailEntry : details.entrySet()) {
|
||||||
String value = null;
|
String value = null;
|
||||||
if (detailEntry.getKey().equals(GPU.Keys.pciDevice.toString())) {
|
if (detailEntry.getKey().equals(GPU.Keys.pciDevice.toString())) {
|
||||||
for (GPU.Type type : GPU.Type.values()) {
|
if (detailEntry.getValue() == null) {
|
||||||
if (detailEntry.getValue().equals(type.toString())) {
|
throw new InvalidParameterValueException("Please specify a GPU Card.");
|
||||||
value = detailEntry.getValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (value == null) {
|
|
||||||
throw new InvalidParameterValueException("Please specify valid gpu type");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (detailEntry.getKey().equals(GPU.Keys.vgpuType.toString())) {
|
if (detailEntry.getKey().equals(GPU.Keys.vgpuType.toString())) {
|
||||||
if (details.get(GPU.Keys.pciDevice.toString()).equals(GPU.Type.GPU_Passthrough.toString())) {
|
|
||||||
throw new InvalidParameterValueException("vgpuTypes are supported only with vGPU pciDevice");
|
|
||||||
}
|
|
||||||
if (detailEntry.getValue() == null) {
|
if (detailEntry.getValue() == null) {
|
||||||
throw new InvalidParameterValueException("With vGPU as pciDevice, vGPUType value cannot be null");
|
throw new InvalidParameterValueException("vGPUType value cannot be null");
|
||||||
}
|
}
|
||||||
for (GPU.vGPUType entry : GPU.vGPUType.values()) {
|
for (GPU.vGPUType entry : GPU.vGPUType.values()) {
|
||||||
if (detailEntry.getValue().equals(entry.getType())) {
|
if (detailEntry.getValue().equals(entry.getType())) {
|
||||||
value = entry.getType();
|
value = entry.getType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (value == null || detailEntry.getValue().equals(GPU.vGPUType.passthrough.getType())) {
|
if (value == null) {
|
||||||
throw new InvalidParameterValueException("Please specify valid vGPU type");
|
throw new InvalidParameterValueException("Please specify valid vGPU type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(), detailEntry.getKey(), detailEntry.getValue(), true));
|
detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(), detailEntry.getKey(), detailEntry.getValue(), true));
|
||||||
}
|
|
||||||
// If pciDevice type is passed, put the default VGPU type as 'passthrough'
|
|
||||||
if (details.containsKey(GPU.Keys.pciDevice.toString())
|
|
||||||
&& !details.containsKey(GPU.Keys.vgpuType.toString())) {
|
|
||||||
detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(),
|
|
||||||
GPU.Keys.vgpuType.toString(), GPU.vGPUType.passthrough.getType(), true));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -363,9 +363,11 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
|
|||||||
} else if (_capacityMgr.checkIfHostReachMaxGuestLimit(host)) {
|
} else if (_capacityMgr.checkIfHostReachMaxGuestLimit(host)) {
|
||||||
s_logger.debug("The last Host, hostId: " + host.getId() +
|
s_logger.debug("The last Host, hostId: " + host.getId() +
|
||||||
" already has max Running VMs(count includes system VMs), skipping this and trying other available hosts");
|
" already has max Running VMs(count includes system VMs), skipping this and trying other available hosts");
|
||||||
} else if ((offeringDetails = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.vgpuType.toString())) != null
|
} else if ((offeringDetails = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.vgpuType.toString())) != null) {
|
||||||
&& !_resourceMgr.isGPUDeviceAvailable(host.getId(), offeringDetails.getValue())){
|
ServiceOfferingDetailsVO groupName = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.pciDevice.toString());
|
||||||
s_logger.debug("The last host of this VM does not have required GPU devices available");
|
if(!_resourceMgr.isGPUDeviceAvailable(host.getId(), groupName.getValue(), offeringDetails.getValue())){
|
||||||
|
s_logger.debug("The last host of this VM does not have required GPU devices available");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (host.getStatus() == Status.Up && host.getResourceState() == ResourceState.Enabled) {
|
if (host.getStatus() == Status.Up && host.getResourceState() == ResourceState.Enabled) {
|
||||||
boolean hostTagsMatch = true;
|
boolean hostTagsMatch = true;
|
||||||
|
|||||||
@ -144,7 +144,8 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
|
|||||||
// Set GPU details
|
// Set GPU details
|
||||||
ServiceOfferingDetailsVO offeringDetail = null;
|
ServiceOfferingDetailsVO offeringDetail = null;
|
||||||
if ((offeringDetail = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.vgpuType.toString())) != null) {
|
if ((offeringDetail = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.vgpuType.toString())) != null) {
|
||||||
to.setGpuDevice(_resourceMgr.getGPUDevice(vm.getHostId(), offeringDetail.getValue()));
|
ServiceOfferingDetailsVO groupName = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.pciDevice.toString());
|
||||||
|
to.setGpuDevice(_resourceMgr.getGPUDevice(vm.getHostId(), groupName.getValue(), offeringDetail.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workaround to make sure the TO has the UUID we need for Niciri integration
|
// Workaround to make sure the TO has the UUID we need for Niciri integration
|
||||||
|
|||||||
@ -97,7 +97,6 @@ import com.cloud.exception.DiscoveryException;
|
|||||||
import com.cloud.exception.InvalidParameterValueException;
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
import com.cloud.exception.PermissionDeniedException;
|
import com.cloud.exception.PermissionDeniedException;
|
||||||
import com.cloud.exception.ResourceInUseException;
|
import com.cloud.exception.ResourceInUseException;
|
||||||
import com.cloud.gpu.GPU.vGPUType;
|
|
||||||
import com.cloud.gpu.HostGpuGroupsVO;
|
import com.cloud.gpu.HostGpuGroupsVO;
|
||||||
import com.cloud.gpu.VGPUTypesVO;
|
import com.cloud.gpu.VGPUTypesVO;
|
||||||
import com.cloud.gpu.dao.HostGpuGroupsDao;
|
import com.cloud.gpu.dao.HostGpuGroupsDao;
|
||||||
@ -1349,6 +1348,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
|||||||
|
|
||||||
_gpuAvailability = _hostGpuGroupsDao.createSearchBuilder();
|
_gpuAvailability = _hostGpuGroupsDao.createSearchBuilder();
|
||||||
_gpuAvailability.and("hostId", _gpuAvailability.entity().getHostId(), Op.EQ);
|
_gpuAvailability.and("hostId", _gpuAvailability.entity().getHostId(), Op.EQ);
|
||||||
|
_gpuAvailability.and("groupName", _gpuAvailability.entity().getGroupName(), Op.EQ);
|
||||||
SearchBuilder<VGPUTypesVO> join1 = _vgpuTypesDao.createSearchBuilder();
|
SearchBuilder<VGPUTypesVO> join1 = _vgpuTypesDao.createSearchBuilder();
|
||||||
join1.and("vgpuType", join1.entity().getVgpuType(), Op.EQ);
|
join1.and("vgpuType", join1.entity().getVgpuType(), Op.EQ);
|
||||||
join1.and("remainingCapacity", join1.entity().getRemainingCapacity(), Op.GT);
|
join1.and("remainingCapacity", join1.entity().getRemainingCapacity(), Op.GT);
|
||||||
@ -2508,21 +2508,19 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<HostGpuGroupsVO> listAvailableGPUDevice(long hostId, String vgpuType) {
|
public List<HostGpuGroupsVO> listAvailableGPUDevice(long hostId, String groupName, String vgpuType) {
|
||||||
if (vgpuType == null) {
|
|
||||||
vgpuType = vGPUType.passthrough.getType();
|
|
||||||
}
|
|
||||||
Filter searchFilter = new Filter(VGPUTypesVO.class, "remainingCapacity", false, null, null);
|
Filter searchFilter = new Filter(VGPUTypesVO.class, "remainingCapacity", false, null, null);
|
||||||
SearchCriteria<HostGpuGroupsVO> sc = _gpuAvailability.create();
|
SearchCriteria<HostGpuGroupsVO> sc = _gpuAvailability.create();
|
||||||
sc.setParameters("hostId", hostId);
|
sc.setParameters("hostId", hostId);
|
||||||
|
sc.setParameters("groupName", groupName);
|
||||||
sc.setJoinParameters("groupId", "vgpuType", vgpuType);
|
sc.setJoinParameters("groupId", "vgpuType", vgpuType);
|
||||||
sc.setJoinParameters("groupId", "remainingCapacity", 0);
|
sc.setJoinParameters("groupId", "remainingCapacity", 0);
|
||||||
return _hostGpuGroupsDao.customSearch(sc, searchFilter);
|
return _hostGpuGroupsDao.customSearch(sc, searchFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGPUDeviceAvailable(long hostId, String vgpuType) {
|
public boolean isGPUDeviceAvailable(long hostId, String groupName, String vgpuType) {
|
||||||
if(!listAvailableGPUDevice(hostId, vgpuType).isEmpty()) {
|
if(!listAvailableGPUDevice(hostId, groupName, vgpuType).isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
@ -2533,8 +2531,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GPUDeviceTO getGPUDevice(long hostId, String vgpuType) {
|
public GPUDeviceTO getGPUDevice(long hostId, String groupName, String vgpuType) {
|
||||||
HostGpuGroupsVO gpuDevice = listAvailableGPUDevice(hostId, vgpuType).get(0);
|
HostGpuGroupsVO gpuDevice = listAvailableGPUDevice(hostId, groupName, vgpuType).get(0);
|
||||||
return new GPUDeviceTO(gpuDevice.getGroupName(), vgpuType, null);
|
return new GPUDeviceTO(gpuDevice.getGroupName(), vgpuType, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -558,19 +558,19 @@ public class MockResourceManagerImpl extends ManagerBase implements ResourceMana
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGPUDeviceAvailable(long hostId, String vgpuType) {
|
public boolean isGPUDeviceAvailable(long hostId, String groupName, String vgpuType) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GPUDeviceTO getGPUDevice(long hostId, String vgpuType) {
|
public GPUDeviceTO getGPUDevice(long hostId, String groupName, String vgpuType) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<HostGpuGroupsVO> listAvailableGPUDevice(long hostId, String vgpuType) {
|
public List<HostGpuGroupsVO> listAvailableGPUDevice(long hostId, String groupName, String vgpuType) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -370,25 +370,16 @@
|
|||||||
description: ''
|
description: ''
|
||||||
});
|
});
|
||||||
items.push({
|
items.push({
|
||||||
id: 'GPU_Passthrough',
|
id: 'Group of NVIDIA Corporation GK107GL [GRID K1] GPUs',
|
||||||
description: 'GPU-Passthrough'
|
description: 'NVIDIA GRID K1'
|
||||||
});
|
});
|
||||||
items.push({
|
items.push({
|
||||||
id: 'VGPU',
|
id: 'Group of NVIDIA Corporation GK104GL [GRID K2] GPUs',
|
||||||
description: 'VGPU'
|
description: 'NVIDIA GRID K2'
|
||||||
});
|
});
|
||||||
args.response.success({
|
args.response.success({
|
||||||
data: items
|
data: items
|
||||||
});
|
});
|
||||||
args.$select.change(function() {
|
|
||||||
var $form = $(this).closest('form');
|
|
||||||
var $fields = $form.find('.field');
|
|
||||||
if (($(this).val() == "") || $(this).val() == "GPU-Passthrough") {
|
|
||||||
$form.find('[rel=vgpuType]').hide();
|
|
||||||
} else if ($(this).val() == "VGPU") {
|
|
||||||
$form.find('[rel=vgpuType]').css('display', 'block');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -400,6 +391,10 @@
|
|||||||
id: '',
|
id: '',
|
||||||
description: ''
|
description: ''
|
||||||
});
|
});
|
||||||
|
items.push({
|
||||||
|
id: 'passthrough',
|
||||||
|
description: 'passthrough'
|
||||||
|
});
|
||||||
items.push({
|
items.push({
|
||||||
id: 'GRID K100',
|
id: 'GRID K100',
|
||||||
description: 'GRID K100'
|
description: 'GRID K100'
|
||||||
@ -499,7 +494,7 @@
|
|||||||
array1.push("&serviceofferingdetails[1].value" + "=" + args.data.pciDevice);
|
array1.push("&serviceofferingdetails[1].value" + "=" + args.data.pciDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.data.pciDevice == "VGPU") {
|
if (args.data.vgpuType != "") {
|
||||||
array1.push("&serviceofferingdetails[2].key" + "=" + "vgpuType");
|
array1.push("&serviceofferingdetails[2].key" + "=" + "vgpuType");
|
||||||
array1.push("&serviceofferingdetails[2].value" + "=" + args.data.vgpuType);
|
array1.push("&serviceofferingdetails[2].value" + "=" + args.data.vgpuType);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user