Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/i915/gvt: simplify vgpu configuration management

Instead of copying the information from the vgpu_types arrays into each
intel_vgpu_type structure, just reference this constant information
with a pointer to the already existing data structure, and pass it into
the low-level VGPU creation helpers intead of copying the data into yet
anothe params data structure.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Link: https://lore.kernel.org/r/20220923092652.100656-3-hch@lst.de
[aw: Fold fix from 20220928121110.GA30738@lst.de]
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>

authored by

Christoph Hellwig and committed by
Alex Williamson
1aa3834f 98828955

+81 -145
+10 -10
drivers/gpu/drm/i915/gvt/aperture_gm.c
··· 240 240 } 241 241 242 242 static int alloc_resource(struct intel_vgpu *vgpu, 243 - struct intel_vgpu_creation_params *param) 243 + const struct intel_vgpu_config *conf) 244 244 { 245 245 struct intel_gvt *gvt = vgpu->gvt; 246 246 unsigned long request, avail, max, taken; 247 247 const char *item; 248 248 249 - if (!param->low_gm_sz || !param->high_gm_sz || !param->fence_sz) { 249 + if (!conf->low_mm || !conf->high_mm || !conf->fence) { 250 250 gvt_vgpu_err("Invalid vGPU creation params\n"); 251 251 return -EINVAL; 252 252 } ··· 255 255 max = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE; 256 256 taken = gvt->gm.vgpu_allocated_low_gm_size; 257 257 avail = max - taken; 258 - request = MB_TO_BYTES(param->low_gm_sz); 258 + request = conf->low_mm; 259 259 260 260 if (request > avail) 261 261 goto no_enough_resource; ··· 266 266 max = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE; 267 267 taken = gvt->gm.vgpu_allocated_high_gm_size; 268 268 avail = max - taken; 269 - request = MB_TO_BYTES(param->high_gm_sz); 269 + request = conf->high_mm; 270 270 271 271 if (request > avail) 272 272 goto no_enough_resource; ··· 277 277 max = gvt_fence_sz(gvt) - HOST_FENCE; 278 278 taken = gvt->fence.vgpu_allocated_fence_num; 279 279 avail = max - taken; 280 - request = param->fence_sz; 280 + request = conf->fence; 281 281 282 282 if (request > avail) 283 283 goto no_enough_resource; 284 284 285 285 vgpu_fence_sz(vgpu) = request; 286 286 287 - gvt->gm.vgpu_allocated_low_gm_size += MB_TO_BYTES(param->low_gm_sz); 288 - gvt->gm.vgpu_allocated_high_gm_size += MB_TO_BYTES(param->high_gm_sz); 289 - gvt->fence.vgpu_allocated_fence_num += param->fence_sz; 287 + gvt->gm.vgpu_allocated_low_gm_size += conf->low_mm; 288 + gvt->gm.vgpu_allocated_high_gm_size += conf->high_mm; 289 + gvt->fence.vgpu_allocated_fence_num += conf->fence; 290 290 return 0; 291 291 292 292 no_enough_resource: ··· 340 340 * 341 341 */ 342 342 int intel_vgpu_alloc_resource(struct intel_vgpu *vgpu, 343 - struct intel_vgpu_creation_params *param) 343 + const struct intel_vgpu_config *conf) 344 344 { 345 345 int ret; 346 346 347 - ret = alloc_resource(vgpu, param); 347 + ret = alloc_resource(vgpu, conf); 348 348 if (ret) 349 349 return ret; 350 350
+19 -18
drivers/gpu/drm/i915/gvt/gvt.h
··· 294 294 bool firmware_loaded; 295 295 }; 296 296 297 + struct intel_vgpu_config { 298 + unsigned int low_mm; 299 + unsigned int high_mm; 300 + unsigned int fence; 301 + 302 + /* 303 + * A vGPU with a weight of 8 will get twice as much GPU as a vGPU with 304 + * a weight of 4 on a contended host, different vGPU type has different 305 + * weight set. Legal weights range from 1 to 16. 306 + */ 307 + unsigned int weight; 308 + enum intel_vgpu_edid edid; 309 + const char *name; 310 + }; 311 + 297 312 #define NR_MAX_INTEL_VGPU_TYPES 20 298 313 struct intel_vgpu_type { 299 314 char name[16]; 315 + const struct intel_vgpu_config *conf; 300 316 unsigned int avail_instance; 301 - unsigned int low_gm_size; 302 - unsigned int high_gm_size; 303 - unsigned int fence; 304 - unsigned int weight; 305 - enum intel_vgpu_edid resolution; 306 317 }; 307 318 308 319 struct intel_gvt { ··· 447 436 /* ring context size i.e. the first 0x50 dwords*/ 448 437 #define RING_CTX_SIZE 320 449 438 450 - struct intel_vgpu_creation_params { 451 - __u64 low_gm_sz; /* in MB */ 452 - __u64 high_gm_sz; /* in MB */ 453 - __u64 fence_sz; 454 - __u64 resolution; 455 - __s32 primary; 456 - __u64 vgpu_id; 457 - 458 - __u32 weight; 459 - }; 460 - 461 439 int intel_vgpu_alloc_resource(struct intel_vgpu *vgpu, 462 - struct intel_vgpu_creation_params *param); 440 + const struct intel_vgpu_config *conf); 463 441 void intel_vgpu_reset_resource(struct intel_vgpu *vgpu); 464 442 void intel_vgpu_free_resource(struct intel_vgpu *vgpu); 465 443 void intel_vgpu_write_fence(struct intel_vgpu *vgpu, ··· 494 494 495 495 struct intel_vgpu *intel_gvt_create_idle_vgpu(struct intel_gvt *gvt); 496 496 void intel_gvt_destroy_idle_vgpu(struct intel_vgpu *vgpu); 497 - int intel_gvt_create_vgpu(struct intel_vgpu *vgpu, struct intel_vgpu_type *type); 497 + int intel_gvt_create_vgpu(struct intel_vgpu *vgpu, 498 + const struct intel_vgpu_config *conf); 498 499 void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu); 499 500 void intel_gvt_release_vgpu(struct intel_vgpu *vgpu); 500 501 void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
+5 -5
drivers/gpu/drm/i915/gvt/kvmgt.c
··· 151 151 return sprintf(buf, "low_gm_size: %dMB\nhigh_gm_size: %dMB\n" 152 152 "fence: %d\nresolution: %s\n" 153 153 "weight: %d\n", 154 - BYTES_TO_MB(type->low_gm_size), 155 - BYTES_TO_MB(type->high_gm_size), 156 - type->fence, vgpu_edid_str(type->resolution), 157 - type->weight); 154 + BYTES_TO_MB(type->conf->low_mm), 155 + BYTES_TO_MB(type->conf->high_mm), 156 + type->conf->fence, vgpu_edid_str(type->conf->edid), 157 + type->conf->weight); 158 158 } 159 159 160 160 static ssize_t name_show(struct mdev_type *mtype, ··· 1559 1559 return -EINVAL; 1560 1560 1561 1561 vgpu->gvt = gvt; 1562 - return intel_gvt_create_vgpu(vgpu, type); 1562 + return intel_gvt_create_vgpu(vgpu, type->conf); 1563 1563 } 1564 1564 1565 1565 static void intel_vgpu_release_dev(struct vfio_device *vfio_dev)
+47 -112
drivers/gpu/drm/i915/gvt/vgpu.c
··· 73 73 drm_WARN_ON(&i915->drm, sizeof(struct vgt_if) != VGT_PVINFO_SIZE); 74 74 } 75 75 76 + /* 77 + * vGPU type name is defined as GVTg_Vx_y which contains the physical GPU 78 + * generation type (e.g V4 as BDW server, V5 as SKL server). 79 + * 80 + * Depening on the physical SKU resource, we might see vGPU types like 81 + * GVTg_V4_8, GVTg_V4_4, GVTg_V4_2, etc. We can create different types of 82 + * vGPU on same physical GPU depending on available resource. Each vGPU 83 + * type will have a different number of avail_instance to indicate how 84 + * many vGPU instance can be created for this type. 85 + */ 76 86 #define VGPU_MAX_WEIGHT 16 77 87 #define VGPU_WEIGHT(vgpu_num) \ 78 88 (VGPU_MAX_WEIGHT / (vgpu_num)) 79 89 80 - static const struct { 81 - unsigned int low_mm; 82 - unsigned int high_mm; 83 - unsigned int fence; 84 - 85 - /* A vGPU with a weight of 8 will get twice as much GPU as a vGPU 86 - * with a weight of 4 on a contended host, different vGPU type has 87 - * different weight set. Legal weights range from 1 to 16. 88 - */ 89 - unsigned int weight; 90 - enum intel_vgpu_edid edid; 91 - const char *name; 92 - } vgpu_types[] = { 93 - /* Fixed vGPU type table */ 90 + static const struct intel_vgpu_config intel_vgpu_configs[] = { 94 91 { MB_TO_BYTES(64), MB_TO_BYTES(384), 4, VGPU_WEIGHT(8), GVT_EDID_1024_768, "8" }, 95 92 { MB_TO_BYTES(128), MB_TO_BYTES(512), 4, VGPU_WEIGHT(4), GVT_EDID_1920_1200, "4" }, 96 93 { MB_TO_BYTES(256), MB_TO_BYTES(1024), 4, VGPU_WEIGHT(2), GVT_EDID_1920_1200, "2" }, ··· 103 106 */ 104 107 int intel_gvt_init_vgpu_types(struct intel_gvt *gvt) 105 108 { 106 - unsigned int num_types; 107 - unsigned int i, low_avail, high_avail; 108 - unsigned int min_low; 109 - 110 - /* vGPU type name is defined as GVTg_Vx_y which contains 111 - * physical GPU generation type (e.g V4 as BDW server, V5 as 112 - * SKL server). 113 - * 114 - * Depend on physical SKU resource, might see vGPU types like 115 - * GVTg_V4_8, GVTg_V4_4, GVTg_V4_2, etc. We can create 116 - * different types of vGPU on same physical GPU depending on 117 - * available resource. Each vGPU type will have "avail_instance" 118 - * to indicate how many vGPU instance can be created for this 119 - * type. 120 - * 121 - */ 122 - low_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE; 123 - high_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE; 124 - num_types = ARRAY_SIZE(vgpu_types); 109 + unsigned int low_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE; 110 + unsigned int high_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE; 111 + unsigned int num_types = ARRAY_SIZE(intel_vgpu_configs); 112 + unsigned int i; 125 113 126 114 gvt->types = kcalloc(num_types, sizeof(struct intel_vgpu_type), 127 115 GFP_KERNEL); 128 116 if (!gvt->types) 129 117 return -ENOMEM; 130 118 131 - min_low = MB_TO_BYTES(32); 132 119 for (i = 0; i < num_types; ++i) { 133 - if (low_avail / vgpu_types[i].low_mm == 0) 120 + const struct intel_vgpu_config *conf = &intel_vgpu_configs[i]; 121 + 122 + if (low_avail / conf->low_mm == 0) 134 123 break; 135 - 136 - gvt->types[i].low_gm_size = vgpu_types[i].low_mm; 137 - gvt->types[i].high_gm_size = vgpu_types[i].high_mm; 138 - gvt->types[i].fence = vgpu_types[i].fence; 139 - 140 - if (vgpu_types[i].weight < 1 || 141 - vgpu_types[i].weight > VGPU_MAX_WEIGHT) 124 + if (conf->weight < 1 || conf->weight > VGPU_MAX_WEIGHT) 142 125 goto out_free_types; 143 126 144 - gvt->types[i].weight = vgpu_types[i].weight; 145 - gvt->types[i].resolution = vgpu_types[i].edid; 146 - gvt->types[i].avail_instance = min(low_avail / vgpu_types[i].low_mm, 147 - high_avail / vgpu_types[i].high_mm); 148 - 149 - if (GRAPHICS_VER(gvt->gt->i915) == 8) 150 - sprintf(gvt->types[i].name, "GVTg_V4_%s", 151 - vgpu_types[i].name); 152 - else if (GRAPHICS_VER(gvt->gt->i915) == 9) 153 - sprintf(gvt->types[i].name, "GVTg_V5_%s", 154 - vgpu_types[i].name); 127 + sprintf(gvt->types[i].name, "GVTg_V%u_%s", 128 + GRAPHICS_VER(gvt->gt->i915) == 8 ? 4 : 5, conf->name); 129 + gvt->types[i].conf = conf; 130 + gvt->types[i].avail_instance = min(low_avail / conf->low_mm, 131 + high_avail / conf->high_mm); 155 132 156 133 gvt_dbg_core("type[%d]: %s avail %u low %u high %u fence %u weight %u res %s\n", 157 - i, gvt->types[i].name, 158 - gvt->types[i].avail_instance, 159 - gvt->types[i].low_gm_size, 160 - gvt->types[i].high_gm_size, gvt->types[i].fence, 161 - gvt->types[i].weight, 162 - vgpu_edid_str(gvt->types[i].resolution)); 134 + i, gvt->types[i].name, gvt->types[i].avail_instance, 135 + conf->low_mm, conf->high_mm, conf->fence, 136 + conf->weight, vgpu_edid_str(conf->edid)); 163 137 } 164 138 165 139 gvt->num_types = i; ··· 163 195 gvt->fence.vgpu_allocated_fence_num; 164 196 165 197 for (i = 0; i < gvt->num_types; i++) { 166 - low_gm_min = low_gm_avail / gvt->types[i].low_gm_size; 167 - high_gm_min = high_gm_avail / gvt->types[i].high_gm_size; 168 - fence_min = fence_avail / gvt->types[i].fence; 198 + low_gm_min = low_gm_avail / gvt->types[i].conf->low_mm; 199 + high_gm_min = high_gm_avail / gvt->types[i].conf->high_mm; 200 + fence_min = fence_avail / gvt->types[i].conf->fence; 169 201 gvt->types[i].avail_instance = min(min(low_gm_min, high_gm_min), 170 202 fence_min); 171 203 172 204 gvt_dbg_core("update type[%d]: %s avail %u low %u high %u fence %u\n", 173 205 i, gvt->types[i].name, 174 - gvt->types[i].avail_instance, gvt->types[i].low_gm_size, 175 - gvt->types[i].high_gm_size, gvt->types[i].fence); 206 + gvt->types[i].avail_instance, gvt->types[i].conf->low_mm, 207 + gvt->types[i].conf->high_mm, gvt->types[i].conf->fence); 176 208 } 177 209 } 178 210 ··· 333 365 vfree(vgpu); 334 366 } 335 367 336 - static int __intel_gvt_create_vgpu(struct intel_vgpu *vgpu, 337 - struct intel_vgpu_creation_params *param) 368 + int intel_gvt_create_vgpu(struct intel_vgpu *vgpu, 369 + const struct intel_vgpu_config *conf) 338 370 { 339 371 struct intel_gvt *gvt = vgpu->gvt; 340 372 struct drm_i915_private *dev_priv = gvt->gt->i915; 341 373 int ret; 342 374 343 - gvt_dbg_core("low %llu MB high %llu MB fence %llu\n", 344 - param->low_gm_sz, param->high_gm_sz, 345 - param->fence_sz); 375 + gvt_dbg_core("low %u MB high %u MB fence %u\n", 376 + BYTES_TO_MB(conf->low_mm), BYTES_TO_MB(conf->high_mm), 377 + conf->fence); 346 378 379 + mutex_lock(&gvt->lock); 347 380 ret = idr_alloc(&gvt->vgpu_idr, vgpu, IDLE_VGPU_IDR + 1, GVT_MAX_VGPU, 348 381 GFP_KERNEL); 349 382 if (ret < 0) 350 - return ret; 383 + goto out_unlock;; 351 384 352 385 vgpu->id = ret; 353 - vgpu->sched_ctl.weight = param->weight; 386 + vgpu->sched_ctl.weight = conf->weight; 354 387 mutex_init(&vgpu->vgpu_lock); 355 388 mutex_init(&vgpu->dmabuf_lock); 356 389 INIT_LIST_HEAD(&vgpu->dmabuf_obj_list_head); 357 390 INIT_RADIX_TREE(&vgpu->page_track_tree, GFP_KERNEL); 358 391 idr_init_base(&vgpu->object_idr, 1); 359 - intel_vgpu_init_cfg_space(vgpu, param->primary); 392 + intel_vgpu_init_cfg_space(vgpu, 1); 360 393 vgpu->d3_entered = false; 361 394 362 395 ret = intel_vgpu_init_mmio(vgpu); 363 396 if (ret) 364 397 goto out_clean_idr; 365 398 366 - ret = intel_vgpu_alloc_resource(vgpu, param); 399 + ret = intel_vgpu_alloc_resource(vgpu, conf); 367 400 if (ret) 368 401 goto out_clean_vgpu_mmio; 369 402 ··· 378 409 if (ret) 379 410 goto out_clean_gtt; 380 411 381 - ret = intel_vgpu_init_display(vgpu, param->resolution); 412 + ret = intel_vgpu_init_display(vgpu, conf->edid); 382 413 if (ret) 383 414 goto out_clean_opregion; 384 415 ··· 403 434 if (ret) 404 435 goto out_clean_sched_policy; 405 436 437 + intel_gvt_update_vgpu_types(gvt); 438 + intel_gvt_update_reg_whitelist(vgpu); 439 + mutex_unlock(&gvt->lock); 406 440 return 0; 407 441 408 442 out_clean_sched_policy: ··· 424 452 intel_vgpu_clean_mmio(vgpu); 425 453 out_clean_idr: 426 454 idr_remove(&gvt->vgpu_idr, vgpu->id); 427 - return ret; 428 - } 429 - 430 - /** 431 - * intel_gvt_create_vgpu - create a virtual GPU 432 - * @gvt: GVT device 433 - * @type: type of the vGPU to create 434 - * 435 - * This function is called when user wants to create a virtual GPU. 436 - * 437 - * Returns: 438 - * pointer to intel_vgpu, error pointer if failed. 439 - */ 440 - int intel_gvt_create_vgpu(struct intel_vgpu *vgpu, struct intel_vgpu_type *type) 441 - { 442 - struct intel_gvt *gvt = vgpu->gvt; 443 - struct intel_vgpu_creation_params param; 444 - int ret; 445 - 446 - param.primary = 1; 447 - param.low_gm_sz = type->low_gm_size; 448 - param.high_gm_sz = type->high_gm_size; 449 - param.fence_sz = type->fence; 450 - param.weight = type->weight; 451 - param.resolution = type->resolution; 452 - 453 - /* XXX current param based on MB */ 454 - param.low_gm_sz = BYTES_TO_MB(param.low_gm_sz); 455 - param.high_gm_sz = BYTES_TO_MB(param.high_gm_sz); 456 - 457 - mutex_lock(&gvt->lock); 458 - ret = __intel_gvt_create_vgpu(vgpu, &param); 459 - if (!ret) { 460 - /* calculate left instance change for types */ 461 - intel_gvt_update_vgpu_types(gvt); 462 - intel_gvt_update_reg_whitelist(vgpu); 463 - } 455 + out_unlock: 464 456 mutex_unlock(&gvt->lock); 465 - 466 457 return ret; 467 458 } 468 459