Skip to content

Commit

Permalink
dkms: optimize the dg2 kernel driver loading time
Browse files Browse the repository at this point in the history
loaded the dGPU drvier as kernel module on boot stage,
before that the driver loaded after init process lunched
that took more time for driver working.

Tracked-On: OAM-124024
Signed-off-by: Wang, Yiyang <[email protected]>
  • Loading branch information
wangyiyanga committed Sep 16, 2024
1 parent 5aff8c2 commit b3e25e5
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 8 deletions.
46 changes: 45 additions & 1 deletion drivers/gpu/drm/i915/i915_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
*
*/

#include <linux/firmware.h>

#include <drm/drm_color_mgmt.h>
#include <drm/drm_drv.h>
#include <drm/i915_pciids.h>
Expand Down Expand Up @@ -1022,6 +1024,45 @@ static bool intel_mmio_bar_valid(struct pci_dev *pdev, struct intel_device_info
return i915_pci_resource_valid(pdev, intel_mmio_bar(intel_info->__runtime.graphics.ip.ver));
}

extern int gfx_load_module(void *buf, int len);

static void gfx_out_of_tree_load(struct device *dev)
{
const struct firmware *fw = NULL;
int err;
void *buf;

err = firmware_request_nowarn(&fw, "i915/compat.ko", dev);
if (err) {
DRM_ERROR("compat load failed: %d\n", err);
return;
}
buf = __vmalloc((unsigned long)fw->size, GFP_KERNEL | __GFP_NOWARN);
memcpy(buf, fw->data, fw->size);
gfx_load_module(buf, fw->size);
DRM_INFO("compat loaded\n");

err = firmware_request_nowarn(&fw, "i915/intel_vsec.ko", dev);
if (err) {
DRM_ERROR("intel_vsec load failed: %d\n", err);
return;
}
buf = __vmalloc((unsigned long)fw->size, GFP_KERNEL | __GFP_NOWARN);
memcpy(buf, fw->data, fw->size);
gfx_load_module(buf, fw->size);
DRM_INFO("intel_vsec loaded\n");

err = firmware_request_nowarn(&fw, "i915/i915_ag.ko", dev);
if (err) {
DRM_ERROR("i915_ag load failed: %d\n", err);
return;
}
buf = __vmalloc((unsigned long)fw->size, GFP_KERNEL | __GFP_NOWARN);
memcpy(buf, fw->data, fw->size);
gfx_load_module(buf, fw->size);
DRM_INFO("i915_ag loaded\n");
}

static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct intel_device_info *intel_info =
Expand Down Expand Up @@ -1147,7 +1188,10 @@ static struct pci_driver i915_pci_driver = {

int i915_pci_register_driver(void)
{
return pci_register_driver(&i915_pci_driver);
int ret;
ret = pci_register_driver(&i915_pci_driver);
gfx_out_of_tree_load(NULL);
return ret;
}

void i915_pci_unregister_driver(void)
Expand Down
29 changes: 22 additions & 7 deletions kernel/module/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2734,7 +2734,7 @@ static int unknown_module_param_cb(char *param, char *val, const char *modname,
* zero, and we rely on this for optional sections.
*/
static int load_module(struct load_info *info, const char __user *uargs,
int flags)
int flags, bool no_args)
{
struct module *mod;
long err = 0;
Expand Down Expand Up @@ -2861,10 +2861,17 @@ static int load_module(struct load_info *info, const char __user *uargs,
flush_module_icache(mod);

/* Now copy in args */
mod->args = strndup_user(uargs, ~0UL >> 1);
if (IS_ERR(mod->args)) {
err = PTR_ERR(mod->args);
goto free_arch_cleanup;
if (!no_args) {
mod->args = strndup_user(uargs, ~0UL >> 1);
if (IS_ERR(mod->args)) {
pr_debug("%s mod->args error\n", __func__);
err = PTR_ERR(mod->args);
goto free_arch_cleanup;
}
pr_debug("%s mod->args: %llx \n", __func__, (u64)mod->args);
} else {
char *arg = "";
mod->args = kmemdup(arg, strlen(arg) + 1, GFP_KERNEL);
}

init_build_id(mod, info);
Expand Down Expand Up @@ -2977,7 +2984,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
if (err)
return err;

return load_module(&info, uargs, 0);
return load_module(&info, uargs, 0, false);
}

SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
Expand Down Expand Up @@ -3013,7 +3020,15 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
info.len = len;
}

return load_module(&info, uargs, flags);
return load_module(&info, uargs, flags, false);
}

int gfx_load_module(void *buf, int len)
{
struct load_info info = { };
info.hdr = buf;
info.len = len;
return load_module(&info, NULL, 0, true);
}

static inline int within(unsigned long addr, void *start, unsigned long size)
Expand Down

0 comments on commit b3e25e5

Please sign in to comment.