Summary: | =x11-drivers/nvidia-drivers-450.57-r1 - .../work/kernel/nvidia-uvm/uvm8_va_range.h:758:5: error: implicit declaration of function ‘smp_read_barrier_depends’ [-Werror=implicit-function-declaration] | ||
---|---|---|---|
Product: | Gentoo Linux | Reporter: | brookebasile |
Component: | Current packages | Assignee: | David Seifert <soap> |
Status: | RESOLVED OBSOLETE | ||
Severity: | normal | CC: | ionen, krinpaus |
Priority: | Normal | ||
Version: | unspecified | ||
Hardware: | AMD64 | ||
OS: | Linux | ||
Whiteboard: | |||
Package list: | Runtime testing required: | --- | |
Attachments: | build.log |
Description
brookebasile
2020-08-11 02:11:02 UTC
This issue was also brought up on the forums (albeit no solution as of the writing of this), posting given a lot of info was given and could be a useful reference. https://forums.gentoo.org/viewtopic-t-1117385.html Did some more digging into this, it looks like this error is likely the culprit: In file included from /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-uvm/uvm8_global.c:31: /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-uvm/uvm8_va_range.h: In function ‘uvm_va_range_block’: /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-uvm/uvm8_va_range.h:758:5: error: implicit declaration of function ‘smp_read_barrier_depends’ [-Werror=implicit-function-declaration] 758 | smp_read_barrier_depends(); | ^~~~~~~~~~~~~~~~~~~~~~~~ Checked the header files in uvm8_va_range.h and couldn't find a declaration of smp_read_barrier_depends() anywhere. Specifically, nv-kref.h includes <asm/barrier.h>, which shows no declaration of smp_read_barrier_depends in 5.8.0 kernel. Did some more digging from there and I found this LKML reference citing that smp_read_barrier_depends() macros have been removed from the kernel: https://lore.kernel.org/lkml/20200710165203.31284-11-will@kernel.org/ Not sure if they are aware of this upstream, I'm a newbie to kernel hacking so sorry if any of this was already obvious :) I guess you do not have CONFIG_MEMBARRIER set. (In reply to Jeroen Roovers from comment #3) > I guess you do not have CONFIG_MEMBARRIER set. I just checked and it is enabled in my kernel config. Same here: # grep CONFIG_MEMBARRIER /usr/src/linux/.config CONFIG_MEMBARRIER=y So it looks like nvidia is using a lot of functions that were deprecated in the last 1-2 months. I went ahead and removed the use of smp_read_barrier_depends() entirely, as according to this LKML email: https://lore.kernel.org/lkml/20200710165203.31284-6-will@kernel.org/ READ_ONCE() can be used to provide dependency ordering (via its call to __READ_ONCE). The locations in the code that relied on smp_read_barrier_depends() utilize atomic_long_read(), which is a wrapper around atomic64_read(), which uses READ_ONCE(): // kernel/nvidia-uvm/uvm8_va_range.h: static uvm_va_block_t *uvm_va_range_block(uvm_va_range_t *va_range, size_t index) { uvm_va_block_t *block; UVM_ASSERT(va_range->type == UVM_VA_RANGE_TYPE_MANAGED); UVM_ASSERT(index < uvm_va_range_num_blocks(va_range)); block = (uvm_va_block_t *)atomic_long_read(&va_range->blocks[index]); // Later accesses in this thread will read state out of block, potentially // as soon as the block pointer is updated by another thread. We have to // make sure that any initialization of this block by the creating thread is // visible to later accesses in this thread, which requires a data // dependency barrier. smp_read_barrier_depends(); return block; } // kernel/nvidia-uvm/uvm8_tools.c: static uvm_tools_event_tracker_t *tools_event_tracker(struct file *filp) { long event_tracker = atomic_long_read((atomic_long_t *)&filp->private_data); smp_read_barrier_depends(); return (uvm_tools_event_tracker_t *)event_tracker; } // asm-generic/atomic-long.h: static __always_inline long atomic_long_read(const atomic_long_t *v) { return atomic64_read(v); } // asm/atomic.h #define atomic64_read(v) READ_ONCE((v)->counter) So I thought it would be OK to just remove the references to smp_read_barrier_depends() based on the rework of READ_ONCE() described in the above LKML email. That built fine, however, more errors popped up after moving past that stage of the compilation: In file included from /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-drm/nvidia-drm-gem-nvkms-memory.h:30, from /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-drm/nvidia-drm-fb.h:38, from /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-drm/nvidia-drm-drv.c:27: /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-drm/nvidia-drm-gem.h: In function ‘nv_drm_gem_object_unreference_unlocked’: /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-drm/nvidia-drm-gem.h:99:5: error: implicit declaration of function ‘drm_gem_object_put_unlocked’; did you mean ‘drm_gem_object_put_locke ’? [-Werror=implicit-function-declaration] 99 | drm_gem_object_put_unlocked(&nv_gem->base); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ | drm_gem_object_put_locked Git grep shows drm_gem_object_put_locked is deprecated: // drm/drm_drv.h 330 /** 331 * @gem_free_object_unlocked: deconstructor for drm_gem_objects 332 * 333 * This is deprecated and should not be used by new drivers. Use 334 * &drm_gem_object_funcs.free instead. 335 */ /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-drm/nvidia-drm-drv.c:722:6: error: ‘struct drm_driver’ has no member named ‘gem_free_object’; did you mean ‘gem_open_object’? 722 | .gem_free_object = nv_drm_gem_free, | ^~~~~~~~~~~~~~~ | gem_open_object /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-drm/nvidia-drm-drv.c:722:31: error: initialization of ‘const struct drm_ioctl_desc *’ from incompatible pointer type ‘void (*)(struct drm_gem_object *)’ [-Werror=incompatible-pointer-types] 722 | .gem_free_object = nv_drm_gem_free, | ^~~~~~~~~~~~~~~ *** Same here: // drm/drm_drv.h 330 /** 331 * @gem_free_object_unlocked: deconstructor for drm_gem_objects 332 * 333 * This is deprecated and should not be used by new drivers. Use 334 * &drm_gem_object_funcs.free instead. 335 */ *** /portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-modeset/nv-kthread-q.o /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-drm/nvidia-drm-utils.c: In function ‘nvkms_display_mode_to_drm_mode’: /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-drm/nvidia-drm-utils.c:106:9: error: ‘struct drm_display_mode’ has no member named ‘vrefresh’ 106 | mode->vrefresh = (displayMode->timings.refreshRate + 500) / 1000; /* In Hz */ | ^~ /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-drm/nvidia-drm-utils.c: In function ‘drm_mode_to_nvkms_display_mode’: /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-drm/nvidia-drm-utils.c:162:36: error: ‘const struct drm_display_mode’ has no member named ‘vrefresh’ 162 | dst->timings.refreshRate = src->vrefresh * 1000; mode->vrefresh is also deprecated, see 0425662fdf05: drm: Nuke mode->vrefresh According to this patch (https://lore.kernel.org/lkml/20200811182107.6515-1-sumit.semwal@linaro.org/t/#u): v4: Since "0425662fdf05: drm: Nuke mode->vrefresh", we have to calculate vrefresh on demand. Update for it. *** And this error: /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-drm/nvidia-drm-drv.c:722:31: note: (near initialization for ‘nv_drm_driver.ioctls’) /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-drm/nvidia-drm-drv.c: In function ‘nv_drm_update_drm_driver_features’: /var/tmp/portage/x11-drivers/nvidia-drivers-450.57-r1/work/kernel/nvidia-drm/nvidia-drm-drv.c:784:36: error: assignment to ‘void (*)(struct drm_device *, struct drm_file *, bool)’ {aka ‘void (*)(struct drm_device *, struct drm_file *, _Bool)’} from incompatible pointer type ‘int (*)(struct drm_device *, struct drm_file *, bool)’ {aka ‘int (*)(struct drm_device *, struct drm_file *, _Bool)’} [-Werror=incompatible-pointer-types] 784 | nv_drm_driver.master_set = nv_drm_master_set; *** So it seems like they're using a lot of macros/functions that have been deprecated, I'm not sure if they're aware of this upstream...? This is a snippet of code I`m using to build nvidia-drivers-390 on kernel 5.9. NV_SMP_READ_BARRIER_DEPENDS_PRESENT macro check if smp_read_barrier_depends() is defined otherwise it just use smp_rmb() as replacement function call. Assuming the kernel is compiled with CONFIG_SMP=y, smp_rmb() is defined in <asm-generic/barrier.c> for the latest kernels. So far, so good, my patched nvidia-drivers-390 works like a charm with the latest kernels. ***** diff --git a/kernel/nvidia-uvm/uvm8_tools.c b/kernel/nvidia-uvm/uvm8_tools.c --- a/kernel/nvidia-uvm/uvm8_tools.c +++ b/kernel/nvidia-uvm/uvm8_tools.c @@ -190,11 +190,15 @@ static NV_STATUS tools_update_status(uvm_va_space_t *va_space); static uvm_tools_event_tracker_t *tools_event_tracker(struct file *filp) { long event_tracker = atomic_long_read((atomic_long_t *)&filp->private_data); +#if defined(NV_SMP_READ_BARRIER_DEPENDS_PRESENT) smp_read_barrier_depends(); +#else + smp_rmb(); +#endif return (uvm_tools_event_tracker_t *)event_tracker; } static bool tracker_is_queue(uvm_tools_event_tracker_t *event_tracker) { ***** Is this still relevant on the latest drivers? I dont get any issues (In reply to David Seifert from comment #8) > Is this still relevant on the latest drivers? I dont get any issues Had a look at drivers and bits regarding smp_read_barrier_depends changed. Only used in 1 place (instead of two), and guarded by a #ifdef. Fairly convinced this is obsolete. |