diff options
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_msg.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c index 089046fa21be..06d9e106e3c5 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c @@ -85,7 +85,14 @@ struct rpc_channel { u32 cookie_low; }; - +#if IS_ENABLED(CONFIG_DRM_VMWGFX_MKSSTATS) +/* Kernel mksGuestStats counter names and desciptions; same order as enum mksstat_kern_stats_t */ +static const char* const mksstat_kern_name_desc[MKSSTAT_KERN_COUNT][2] = +{ + { "vmw_execbuf_ioctl", "vmw_execbuf_ioctl" }, + { "vmw_cotable_resize", "vmw_cotable_resize" }, +}; +#endif /** * vmw_open_channel @@ -695,12 +702,6 @@ static inline void hypervisor_ppn_remove(PPN64 pfn) /* Header to the text description of mksGuestStat instance descriptor */ #define MKSSTAT_KERNEL_DESCRIPTION "vmwgfx" -/* Kernel mksGuestStats counter names and desciptions; same order as enum mksstat_kern_stats_t */ -static const char* const mksstat_kern_name_desc[MKSSTAT_KERN_COUNT][2] = -{ - { "vmw_execbuf_ioctl", "vmw_execbuf_ioctl" }, -}; - /** * mksstat_init_record: Initializes an MKSGuestStatCounter-based record * for the respective mksGuestStat index. @@ -786,6 +787,7 @@ static int mksstat_init_kern_id(struct page **ppage) /* Set up all kernel-internal counters and corresponding structures */ pstrs_acc = pstrs; pstrs_acc = mksstat_init_record_time(MKSSTAT_KERN_EXECBUF, pstat, pinfo, pstrs_acc); + pstrs_acc = mksstat_init_record_time(MKSSTAT_KERN_COTABLE_RESIZE, pstat, pinfo, pstrs_acc); /* Add new counters above, in their order of appearance in mksstat_kern_stats_t */ @@ -1014,8 +1016,6 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data, struct vmw_private *const dev_priv = vmw_priv(dev); - struct page *page; - MKSGuestStatInstanceDescriptor *pdesc; const size_t num_pages_stat = PFN_UP(arg->stat_len); const size_t num_pages_info = PFN_UP(arg->info_len); const size_t num_pages_strs = PFN_UP(arg->strs_len); @@ -1023,10 +1023,13 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data, long nr_pinned_stat; long nr_pinned_info; long nr_pinned_strs; - struct page *pages_stat[ARRAY_SIZE(pdesc->statPPNs)]; - struct page *pages_info[ARRAY_SIZE(pdesc->infoPPNs)]; - struct page *pages_strs[ARRAY_SIZE(pdesc->strsPPNs)]; + MKSGuestStatInstanceDescriptor *pdesc; + struct page *page = NULL; + struct page **pages_stat = NULL; + struct page **pages_info = NULL; + struct page **pages_strs = NULL; size_t i, slot; + int ret_err = -ENOMEM; arg->id = -1; @@ -1054,13 +1057,23 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data, BUG_ON(dev_priv->mksstat_user_pages[slot]); + /* Allocate statically-sized temp arrays for pages -- too big to keep in frame */ + pages_stat = (struct page **)kmalloc_array( + ARRAY_SIZE(pdesc->statPPNs) + + ARRAY_SIZE(pdesc->infoPPNs) + + ARRAY_SIZE(pdesc->strsPPNs), sizeof(*pages_stat), GFP_KERNEL); + + if (!pages_stat) + goto err_nomem; + + pages_info = pages_stat + ARRAY_SIZE(pdesc->statPPNs); + pages_strs = pages_info + ARRAY_SIZE(pdesc->infoPPNs); + /* Allocate a page for the instance descriptor */ page = alloc_page(GFP_KERNEL | __GFP_ZERO); - if (!page) { - atomic_set(&dev_priv->mksstat_user_pids[slot], 0); - return -ENOMEM; - } + if (!page) + goto err_nomem; /* Set up the instance descriptor */ pdesc = page_address(page); @@ -1075,9 +1088,8 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data, ARRAY_SIZE(pdesc->description) - 1); if (desc_len < 0) { - atomic_set(&dev_priv->mksstat_user_pids[slot], 0); - __free_page(page); - return -EFAULT; + ret_err = -EFAULT; + goto err_nomem; } reset_ppn_array(pdesc->statPPNs, ARRAY_SIZE(pdesc->statPPNs)); @@ -1118,6 +1130,7 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data, DRM_DEV_INFO(dev->dev, "pid=%d arg.description='%.*s' id=%zu\n", current->pid, (int)desc_len, pdesc->description, slot); + kfree(pages_stat); return 0; err_pin_strs: @@ -1132,9 +1145,13 @@ err_pin_stat: if (nr_pinned_stat > 0) unpin_user_pages(pages_stat, nr_pinned_stat); +err_nomem: atomic_set(&dev_priv->mksstat_user_pids[slot], 0); - __free_page(page); - return -ENOMEM; + if (page) + __free_page(page); + kfree(pages_stat); + + return ret_err; } /** |