590.48.01

This commit is contained in:
Maneet Singh
2025-12-18 09:16:33 -08:00
parent a5bfb10e75
commit 2ccbad25e1
51 changed files with 2054 additions and 359 deletions

View File

@@ -79,7 +79,7 @@ ccflags-y += -I$(src)/common/inc
ccflags-y += -I$(src)
ccflags-y += -Wall $(DEFINES) $(INCLUDES) -Wno-cast-qual -Wno-format-extra-args
ccflags-y += -D__KERNEL__ -DMODULE -DNVRM
ccflags-y += -DNV_VERSION_STRING=\"590.44.01\"
ccflags-y += -DNV_VERSION_STRING=\"590.48.01\"
# Include and link Tegra out-of-tree modules.
ifneq ($(wildcard /usr/src/nvidia/nvidia-oot),)

View File

@@ -649,9 +649,9 @@ static inline dma_addr_t nv_phys_to_dma(struct device *dev, NvU64 pa)
#define NV_PRINT_AT(nv_debug_level,at) \
{ \
nv_printf(nv_debug_level, \
"NVRM: VM: %s:%d: 0x%p, %d page(s), count = %d, " \
"NVRM: VM: %s:%d: 0x%p, %d page(s), count = %lld, " \
"page_table = 0x%p\n", __FUNCTION__, __LINE__, at, \
at->num_pages, NV_ATOMIC_READ(at->usage_count), \
at->num_pages, (long long)atomic64_read(&at->usage_count), \
at->page_table); \
}
@@ -919,7 +919,7 @@ struct nv_dma_buf
typedef struct nv_alloc_s {
struct nv_alloc_s *next;
struct device *dev;
atomic_t usage_count;
atomic64_t usage_count;
struct {
NvBool contig : 1;
NvBool guest : 1;
@@ -1248,7 +1248,7 @@ struct nv_pci_tegra_devfreq_dev;
typedef struct nv_linux_state_s {
nv_state_t nv_state;
atomic_t usage_count;
atomic64_t usage_count;
NvU32 suspend_count;
@@ -1627,9 +1627,9 @@ static inline NvBool nv_alloc_release(nv_linux_file_private_t *nvlfp, nv_alloc_t
{
NV_PRINT_AT(NV_DBG_MEMINFO, at);
if (NV_ATOMIC_DEC_AND_TEST(at->usage_count))
if (atomic64_dec_and_test(&at->usage_count))
{
NV_ATOMIC_INC(at->usage_count);
atomic64_inc(&at->usage_count);
at->next = nvlfp->free_list;
nvlfp->free_list = at;

View File

@@ -196,14 +196,33 @@ static inline struct rw_semaphore *nv_mmap_get_lock(struct mm_struct *mm)
* Commit 45ad9f5290dc updated vma_start_write() to call __vma_start_write().
*/
void nv_vma_start_write(struct vm_area_struct *);
static inline void nv_vma_flags_set_word(struct vm_area_struct *vma, unsigned long flags)
{
nv_vma_start_write(vma);
#if defined(NV_VMA_FLAGS_SET_WORD_PRESENT)
vma_flags_set_word(&vma->flags, flags);
#else
ACCESS_PRIVATE(vma, __vm_flags) |= flags;
#endif
}
static inline void nv_vma_flags_clear_word(struct vm_area_struct *vma, unsigned long flags)
{
nv_vma_start_write(vma);
#if defined(NV_VMA_FLAGS_SET_WORD_PRESENT)
vma_flags_clear_word(&vma->flags, flags);
#else
ACCESS_PRIVATE(vma, __vm_flags) &= ~flags;
#endif
}
#endif // !NV_CAN_CALL_VMA_START_WRITE
static inline void nv_vm_flags_set(struct vm_area_struct *vma, vm_flags_t flags)
{
#if !NV_CAN_CALL_VMA_START_WRITE
nv_vma_start_write(vma);
ACCESS_PRIVATE(vma, __vm_flags) |= flags;
#elif defined(NV_VM_AREA_STRUCT_HAS_CONST_VM_FLAGS)
nv_vma_flags_set_word(vma, flags);
#elif defined(NV_VM_FLAGS_SET_PRESENT)
vm_flags_set(vma, flags);
#else
vma->vm_flags |= flags;
@@ -213,9 +232,8 @@ static inline void nv_vm_flags_set(struct vm_area_struct *vma, vm_flags_t flags)
static inline void nv_vm_flags_clear(struct vm_area_struct *vma, vm_flags_t flags)
{
#if !NV_CAN_CALL_VMA_START_WRITE
nv_vma_start_write(vma);
ACCESS_PRIVATE(vma, __vm_flags) &= ~flags;
#elif defined(NV_VM_AREA_STRUCT_HAS_CONST_VM_FLAGS)
nv_vma_flags_clear_word(vma, flags);
#elif defined(NV_VM_FLAGS_SET_PRESENT)
vm_flags_clear(vma, flags);
#else
vma->vm_flags &= ~flags;

View File

@@ -36,6 +36,19 @@
#define NV_MAX_ISR_DELAY_MS (NV_MAX_ISR_DELAY_US / 1000)
#define NV_NSECS_TO_JIFFIES(nsec) ((nsec) * HZ / 1000000000)
/*
* in_hardirq() was added in v5.11-rc1 (2020-12-15) to replace in_irq().
* Fall back to in_irq() for older kernels that don't have in_hardirq().
*/
static inline NvBool nv_in_hardirq(void)
{
#if defined(in_hardirq)
return in_hardirq();
#else
return in_irq();
#endif
}
#if !defined(NV_KTIME_GET_RAW_TS64_PRESENT)
static inline void ktime_get_raw_ts64(struct timespec64 *ts64)
{
@@ -82,7 +95,7 @@ static inline NV_STATUS nv_sleep_us(unsigned int us)
ktime_get_raw_ts64(&tm1);
#endif
if (in_irq() && (us > NV_MAX_ISR_DELAY_US))
if (nv_in_hardirq() && (us > NV_MAX_ISR_DELAY_US))
return NV_ERR_GENERIC;
mdelay_safe_msec = us / 1000;
@@ -127,7 +140,7 @@ static inline NV_STATUS nv_sleep_ms(unsigned int ms)
tm_start = tm_aux;
#endif
if (in_irq() && (ms > NV_MAX_ISR_DELAY_MS))
if (nv_in_hardirq() && (ms > NV_MAX_ISR_DELAY_MS))
{
return NV_ERR_GENERIC;
}

View File

@@ -2114,6 +2114,35 @@ compile_test() {
compile_check_conftest "$CODE" "NV_GET_BACKLIGHT_DEVICE_BY_NAME_PRESENT" "" "functions"
;;
dma_map_ops_has_map_phys)
#
# Determine if .map_phys exists in struct dma_map_ops.
#
# Commit 14cb413af00c ("dma-mapping: remove unused mapping resource callbacks")
# removed .map_resource operation and replaced it with .map_phys.
#
echo "$CONFTEST_PREAMBLE
#include <linux/dma-map-ops.h>
int conftest_dma_map_ops_has_map_phys(void) {
return offsetof(struct dma_map_ops, map_phys);
}
int conftest_dma_map_ops_has_unmap_phys(void) {
return offsetof(struct dma_map_ops, unmap_phys);
}" > conftest$$.c
$CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
rm -f conftest$$.c
if [ -f conftest$$.o ]; then
echo "#define NV_DMA_MAP_OPS_HAS_MAP_PHYS" | append_conftest "types"
rm -f conftest$$.o
return
else
echo "#undef NV_DMA_MAP_OPS_HAS_MAP_PHYS" | append_conftest "types"
return
fi
;;
dma_buf_ops_has_map)
#
# Determine if .map exists in dma_buf_ops.
@@ -3938,6 +3967,27 @@ compile_test() {
compile_check_conftest "$CODE" "NV_PCI_REBAR_GET_POSSIBLE_SIZES_PRESENT" "" "functions"
;;
pci_resize_resource_has_exclude_bars_arg)
#
# Determine if pci_resize_resource() has exclude_bars argument.
#
# exclude_bars argument was added to pci_resize_resource by commit
# 337b1b566db0 (11/14/2025) ("PCI: Fix restoring BARs on BAR resize rollback path")
# in linux-next.
#
CODE="
#include <linux/pci.h>
typeof(pci_resize_resource) conftest_pci_resize_resource_has_exclude_bars_arg;
int __must_check conftest_pci_resize_resource_has_exclude_bars_arg(struct pci_dev *dev,
int i, int size,
int exclude_bars) {
return 0;
}"
compile_check_conftest "$CODE" "NV_PCI_RESIZE_RESOURCE_HAS_EXCLUDE_BARS_ARG" "" "types"
;;
drm_connector_has_override_edid)
#
# Determine if 'struct drm_connector' has an 'override_edid' member.
@@ -3976,22 +4026,39 @@ compile_test() {
compile_check_conftest "$CODE" "NV_IOMMU_SVA_BIND_DEVICE_HAS_DRVDATA_ARG" "" "types"
;;
vm_area_struct_has_const_vm_flags)
vm_flags_set)
#
# Determine if the 'vm_area_struct' structure has
# const 'vm_flags'.
# Determine if the vm_flags_set() function is present. The
# presence of this function indicates that the vm_flags_clear()
# function is also present.
#
# A union of '__vm_flags' and 'const vm_flags' was added by
# The functions vm_flags_set()/ vm_flags_clear() were added by
# commit bc292ab00f6c ("mm: introduce vma->vm_flags wrapper
# functions") in v6.3.
# functions") in v6.3-rc1 (2023-02-09).
#
CODE="
#include <linux/mm_types.h>
int conftest_vm_area_struct_has_const_vm_flags(void) {
return offsetof(struct vm_area_struct, __vm_flags);
#include <linux/mm.h>
void conftest_vm_flags_set(void) {
vm_flags_set();
}"
compile_check_conftest "$CODE" "NV_VM_AREA_STRUCT_HAS_CONST_VM_FLAGS" "" "types"
compile_check_conftest "$CODE" "NV_VM_FLAGS_SET_PRESENT" "" "functions"
;;
vma_flags_set_word)
#
# Determine if the vma_flags_set_word() function is present.
#
# Added by commit c3f7c506e8f1 ("mm: introduce VMA flags bitmap type")
# in v6.19-rc1.
#
CODE="
#include <linux/mm.h>
void conftest_vma_flags_set_word(void) {
vma_flags_set_word();
}"
compile_check_conftest "$CODE" "NV_VMA_FLAGS_SET_WORD_PRESENT" "" "functions"
;;
drm_driver_has_dumb_destroy)

View File

@@ -1554,7 +1554,7 @@ static int __nv_drm_cursor_atomic_check(struct drm_plane *plane,
WARN_ON(nv_plane->layer_idx != NVKMS_KAPI_LAYER_INVALID_IDX);
nv_drm_for_each_crtc_in_state(plane_state->state, crtc, crtc_state, i) {
for_each_new_crtc_in_state(plane_state->state, crtc, crtc_state, i) {
struct nv_drm_crtc_state *nv_crtc_state = to_nv_crtc_state(crtc_state);
struct NvKmsKapiHeadRequestedConfig *head_req_config =
&nv_crtc_state->req_config;
@@ -1600,7 +1600,7 @@ static int nv_drm_plane_atomic_check(struct drm_plane *plane,
WARN_ON(nv_plane->layer_idx == NVKMS_KAPI_LAYER_INVALID_IDX);
nv_drm_for_each_crtc_in_state(plane_state->state, crtc, crtc_state, i) {
for_each_new_crtc_in_state(plane_state->state, crtc, crtc_state, i) {
struct nv_drm_crtc_state *nv_crtc_state = to_nv_crtc_state(crtc_state);
struct NvKmsKapiHeadRequestedConfig *head_req_config =
&nv_crtc_state->req_config;
@@ -2430,7 +2430,7 @@ static int nv_drm_crtc_atomic_check(struct drm_crtc *crtc,
req_config->flags.displaysChanged = NV_TRUE;
nv_drm_for_each_connector_in_state(crtc_state->state,
for_each_new_connector_in_state(crtc_state->state,
connector, connector_state, j) {
if (connector_state->crtc != crtc) {
continue;

View File

@@ -54,7 +54,7 @@
* drm_atomic_helper_disable_all() is copied from
* linux/drivers/gpu/drm/drm_atomic_helper.c and modified to use
* nv_drm_for_each_crtc instead of drm_for_each_crtc to loop over all crtcs,
* use nv_drm_for_each_*_in_state instead of for_each_connector_in_state to loop
* use for_each_new_*_in_state instead of for_each_connector_in_state to loop
* over all modeset object states, and use drm_atomic_state_free() if
* drm_atomic_state_put() is not available.
*
@@ -139,13 +139,13 @@ int nv_drm_atomic_helper_disable_all(struct drm_device *dev,
plane_state->rotation = DRM_MODE_ROTATE_0;
}
nv_drm_for_each_connector_in_state(state, conn, conn_state, i) {
for_each_new_connector_in_state(state, conn, conn_state, i) {
ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
if (ret < 0)
goto free;
}
nv_drm_for_each_plane_in_state(state, plane, plane_state, i) {
for_each_new_plane_in_state(state, plane, plane_state, i) {
ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
if (ret < 0)
goto free;

View File

@@ -138,154 +138,6 @@ nv_drm_prime_pages_to_sg(struct drm_device *dev,
int nv_drm_atomic_helper_disable_all(struct drm_device *dev,
struct drm_modeset_acquire_ctx *ctx);
/*
* for_each_connector_in_state(), for_each_crtc_in_state() and
* for_each_plane_in_state() were added by kernel commit
* df63b9994eaf942afcdb946d27a28661d7dfbf2a which was Signed-off-by:
* Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
* Daniel Vetter <daniel.vetter@ffwll.ch>
*
* for_each_connector_in_state(), for_each_crtc_in_state() and
* for_each_plane_in_state() were copied from
* include/drm/drm_atomic.h @
* 21a01abbe32a3cbeb903378a24e504bfd9fe0648
* which has the following copyright and license information:
*
* Copyright (C) 2014 Red Hat
* Copyright (C) 2014 Intel Corp.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rob Clark <robdclark@gmail.com>
* Daniel Vetter <daniel.vetter@ffwll.ch>
*/
/**
* nv_drm_for_each_connector_in_state - iterate over all connectors in an
* atomic update
* @__state: &struct drm_atomic_state pointer
* @connector: &struct drm_connector iteration cursor
* @connector_state: &struct drm_connector_state iteration cursor
* @__i: int iteration cursor, for macro-internal use
*
* This iterates over all connectors in an atomic update. Note that before the
* software state is committed (by calling drm_atomic_helper_swap_state(), this
* points to the new state, while afterwards it points to the old state. Due to
* this tricky confusion this macro is deprecated.
*/
#if !defined(for_each_connector_in_state)
#define nv_drm_for_each_connector_in_state(__state, \
connector, connector_state, __i) \
for ((__i) = 0; \
(__i) < (__state)->num_connector && \
((connector) = (__state)->connectors[__i].ptr, \
(connector_state) = (__state)->connectors[__i].state, 1); \
(__i)++) \
for_each_if (connector)
#else
#define nv_drm_for_each_connector_in_state(__state, \
connector, connector_state, __i) \
for_each_connector_in_state(__state, connector, connector_state, __i)
#endif
/**
* nv_drm_for_each_crtc_in_state - iterate over all CRTCs in an atomic update
* @__state: &struct drm_atomic_state pointer
* @crtc: &struct drm_crtc iteration cursor
* @crtc_state: &struct drm_crtc_state iteration cursor
* @__i: int iteration cursor, for macro-internal use
*
* This iterates over all CRTCs in an atomic update. Note that before the
* software state is committed (by calling drm_atomic_helper_swap_state(), this
* points to the new state, while afterwards it points to the old state. Due to
* this tricky confusion this macro is deprecated.
*/
#if !defined(for_each_crtc_in_state)
#define nv_drm_for_each_crtc_in_state(__state, crtc, crtc_state, __i) \
for ((__i) = 0; \
(__i) < (__state)->dev->mode_config.num_crtc && \
((crtc) = (__state)->crtcs[__i].ptr, \
(crtc_state) = (__state)->crtcs[__i].state, 1); \
(__i)++) \
for_each_if (crtc_state)
#else
#define nv_drm_for_each_crtc_in_state(__state, crtc, crtc_state, __i) \
for_each_crtc_in_state(__state, crtc, crtc_state, __i)
#endif
/**
* nv_drm_for_each_plane_in_state - iterate over all planes in an atomic update
* @__state: &struct drm_atomic_state pointer
* @plane: &struct drm_plane iteration cursor
* @plane_state: &struct drm_plane_state iteration cursor
* @__i: int iteration cursor, for macro-internal use
*
* This iterates over all planes in an atomic update. Note that before the
* software state is committed (by calling drm_atomic_helper_swap_state(), this
* points to the new state, while afterwards it points to the old state. Due to
* this tricky confusion this macro is deprecated.
*/
#if !defined(for_each_plane_in_state)
#define nv_drm_for_each_plane_in_state(__state, plane, plane_state, __i) \
for ((__i) = 0; \
(__i) < (__state)->dev->mode_config.num_total_plane && \
((plane) = (__state)->planes[__i].ptr, \
(plane_state) = (__state)->planes[__i].state, 1); \
(__i)++) \
for_each_if (plane_state)
#else
#define nv_drm_for_each_plane_in_state(__state, plane, plane_state, __i) \
for_each_plane_in_state(__state, plane, plane_state, __i)
#endif
/*
* for_each_new_plane_in_state() was added by kernel commit
* 581e49fe6b411f407102a7f2377648849e0fa37f which was Signed-off-by:
* Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
* Daniel Vetter <daniel.vetter@ffwll.ch>
*
* This commit also added the old_state and new_state pointers to
* __drm_planes_state. Because of this, the best that can be done on kernel
* versions without this macro is for_each_plane_in_state.
*/
/**
* nv_drm_for_each_new_plane_in_state - iterate over all planes in an atomic update
* @__state: &struct drm_atomic_state pointer
* @plane: &struct drm_plane iteration cursor
* @new_plane_state: &struct drm_plane_state iteration cursor for the new state
* @__i: int iteration cursor, for macro-internal use
*
* This iterates over all planes in an atomic update, tracking only the new
* state. This is useful in enable functions, where we need the new state the
* hardware should be in when the atomic commit operation has completed.
*/
#if !defined(for_each_new_plane_in_state)
#define nv_drm_for_each_new_plane_in_state(__state, plane, new_plane_state, __i) \
nv_drm_for_each_plane_in_state(__state, plane, new_plane_state, __i)
#else
#define nv_drm_for_each_new_plane_in_state(__state, plane, new_plane_state, __i) \
for_each_new_plane_in_state(__state, plane, new_plane_state, __i)
#endif
#include <drm/drm_auth.h>
#include <drm/drm_file.h>

View File

@@ -108,8 +108,11 @@ static bool __will_generate_flip_event(struct drm_crtc *crtc,
return false;
}
/* Find out whether primary & overlay flip done events will be generated. */
nv_drm_for_each_plane_in_state(old_crtc_state->state,
/*
* Find out whether primary & overlay flip done events will be generated.
* Only called after drm_atomic_helper_swap_state, so we use old state.
*/
for_each_old_plane_in_state(old_crtc_state->state,
plane, old_plane_state, i) {
if (old_plane_state->crtc != crtc) {
continue;
@@ -193,7 +196,7 @@ static int __nv_drm_convert_in_fences(
return 0;
}
nv_drm_for_each_new_plane_in_state(state, plane, plane_state, i) {
for_each_new_plane_in_state(state, plane, plane_state, i) {
if ((plane->type == DRM_PLANE_TYPE_CURSOR) ||
(plane_state->crtc != crtc) ||
(plane_state->fence == NULL)) {
@@ -334,7 +337,8 @@ static int __nv_drm_get_syncpt_data(
head_reply_config = &reply_config->headReplyConfig[nv_crtc->head];
nv_drm_for_each_plane_in_state(old_crtc_state->state, plane, old_plane_state, i) {
/* Use old state because this is only called after drm_atomic_helper_swap_state */
for_each_old_plane_in_state(old_crtc_state->state, plane, old_plane_state, i) {
struct nv_drm_plane *nv_plane = to_nv_plane(plane);
if (plane->type == DRM_PLANE_TYPE_CURSOR || old_plane_state->crtc != crtc) {
@@ -395,7 +399,7 @@ nv_drm_atomic_apply_modeset_config(struct drm_device *dev,
&(to_nv_atomic_state(state)->config);
struct NvKmsKapiModeSetReplyConfig reply_config = { };
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
int i;
int ret;
@@ -429,18 +433,10 @@ nv_drm_atomic_apply_modeset_config(struct drm_device *dev,
memset(requested_config, 0, sizeof(*requested_config));
/* Loop over affected crtcs and construct NvKmsKapiRequestedModeSetConfig */
nv_drm_for_each_crtc_in_state(state, crtc, crtc_state, i) {
/*
* When committing a state, the new state is already stored in
* crtc->state. When checking a proposed state, the proposed state is
* stored in crtc_state.
*/
struct drm_crtc_state *new_crtc_state =
commit ? crtc->state : crtc_state;
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
struct nv_drm_crtc *nv_crtc = to_nv_crtc(crtc);
if (commit) {
struct drm_crtc_state *old_crtc_state = crtc_state;
struct nv_drm_crtc_state *nv_new_crtc_state =
to_nv_crtc_state(new_crtc_state);
@@ -497,10 +493,11 @@ nv_drm_atomic_apply_modeset_config(struct drm_device *dev,
}
if (commit && nv_dev->supportsSyncpts) {
nv_drm_for_each_crtc_in_state(state, crtc, crtc_state, i) {
/* commit is true so we check old state */
for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
/*! loop over affected crtcs and get NvKmsKapiModeSetReplyConfig */
ret = __nv_drm_get_syncpt_data(
nv_dev, crtc, crtc_state, requested_config, &reply_config);
nv_dev, crtc, old_crtc_state, requested_config, &reply_config);
if (ret != 0) {
return ret;
}
@@ -525,7 +522,7 @@ int nv_drm_atomic_check(struct drm_device *dev,
bool cursor_surface_changed;
bool cursor_only_commit;
nv_drm_for_each_crtc_in_state(state, crtc, crtc_state, i) {
for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
/*
* Committing cursor surface change without any other plane change can
@@ -534,7 +531,7 @@ int nv_drm_atomic_check(struct drm_device *dev,
*/
cursor_surface_changed = false;
cursor_only_commit = true;
nv_drm_for_each_plane_in_state(crtc_state->state, plane, plane_state, j) {
for_each_new_plane_in_state(crtc_state->state, plane, plane_state, j) {
if (plane->type == DRM_PLANE_TYPE_CURSOR) {
if (plane_state->fb != plane->state->fb) {
cursor_surface_changed = true;
@@ -641,7 +638,7 @@ int nv_drm_atomic_commit(struct drm_device *dev,
* Our system already implements such a queue, but due to
* bug 4054608, it is currently not used.
*/
nv_drm_for_each_crtc_in_state(state, crtc, crtc_state, i) {
for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
struct nv_drm_crtc *nv_crtc = to_nv_crtc(crtc);
/*
@@ -748,7 +745,7 @@ int nv_drm_atomic_commit(struct drm_device *dev,
goto done;
}
nv_drm_for_each_crtc_in_state(state, crtc, crtc_state, i) {
for_each_old_crtc_in_state(state, crtc, crtc_state, i) {
struct nv_drm_crtc *nv_crtc = to_nv_crtc(crtc);
struct nv_drm_crtc_state *nv_new_crtc_state =
to_nv_crtc_state(crtc->state);

View File

@@ -30,6 +30,7 @@
#if defined(NV_DRM_DRMP_H_PRESENT)
#include <drm/drmP.h>
#endif
#include <drm/drm_print.h>
#include <drm/drm_device.h>
#include <drm/drm_gem.h>

View File

@@ -64,6 +64,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += vmf_insert_mixed
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_gem_prime_mmap
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_sysfs_connector_property_event
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_sysfs_connector_status_event
NV_CONFTEST_FUNCTION_COMPILE_TESTS += vm_flags_set
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_driver_has_legacy_dev_list
NV_CONFTEST_TYPE_COMPILE_TESTS += vm_ops_fault_removed_vma_arg
@@ -93,7 +94,6 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += reservation_object_reserve_shared_has_num_fenc
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_connector_has_override_edid
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_file_get_master
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_modeset_lock_all_end
NV_CONFTEST_TYPE_COMPILE_TESTS += vm_area_struct_has_const_vm_flags
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_driver_has_dumb_destroy
NV_CONFTEST_TYPE_COMPILE_TESTS += fence_ops_use_64bit_seqno
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_aperture_remove_conflicting_framebuffers_has_driver_arg

View File

@@ -43,8 +43,6 @@
#ifdef UVM_MIGRATE_VMA_SUPPORTED
static struct kmem_cache *g_uvm_migrate_vma_state_cache __read_mostly;
static const gfp_t g_migrate_vma_gfp_flags = NV_UVM_GFP_FLAGS | GFP_HIGHUSER_MOVABLE | __GFP_THISNODE;
static uvm_sgt_t *uvm_select_sgt(uvm_processor_id_t src_id, int src_nid, migrate_vma_state_t *state)
@@ -1497,7 +1495,7 @@ NV_STATUS uvm_migrate_pageable(uvm_migrate_args_t *uvm_migrate_args)
uvm_migrate_args->dst_node_id = uvm_gpu_numa_node(gpu);
}
state = nv_kmem_cache_zalloc(g_uvm_migrate_vma_state_cache, NV_UVM_GFP_FLAGS);
state = uvm_kvmalloc_zero(sizeof(migrate_vma_state_t));
if (!state)
return NV_ERR_NO_MEMORY;
@@ -1519,22 +1517,17 @@ NV_STATUS uvm_migrate_pageable(uvm_migrate_args_t *uvm_migrate_args)
out:
uvm_kvfree(state->dma.sgt_cpu);
uvm_kvfree(state->cpu_page_mask);
kmem_cache_free(g_uvm_migrate_vma_state_cache, state);
uvm_kvfree(state);
return status;
}
NV_STATUS uvm_migrate_pageable_init(void)
{
g_uvm_migrate_vma_state_cache = NV_KMEM_CACHE_CREATE("migrate_vma_state_t", migrate_vma_state_t);
if (!g_uvm_migrate_vma_state_cache)
return NV_ERR_NO_MEMORY;
return NV_OK;
}
void uvm_migrate_pageable_exit(void)
{
kmem_cache_destroy_safe(&g_uvm_migrate_vma_state_cache);
}
#endif

View File

@@ -3360,12 +3360,10 @@ void uvm_pmm_gpu_device_p2p_init(uvm_parent_gpu_t *parent_gpu)
void uvm_pmm_gpu_device_p2p_deinit(uvm_parent_gpu_t *parent_gpu)
{
unsigned long pci_start_pfn = pci_resource_start(parent_gpu->pci_dev,
uvm_device_p2p_static_bar(parent_gpu)) >> PAGE_SHIFT;
struct page *p2p_page;
if (parent_gpu->device_p2p_initialised && !uvm_parent_gpu_is_coherent(parent_gpu)) {
p2p_page = pfn_to_page(pci_start_pfn);
struct page *p2p_page = pfn_to_page(pci_resource_start(parent_gpu->pci_dev,
uvm_device_p2p_static_bar(parent_gpu)) >> PAGE_SHIFT);
devm_memunmap_pages(&parent_gpu->pci_dev->dev, page_pgmap(p2p_page));
}

View File

@@ -729,7 +729,11 @@ static NvBool nv_dma_use_map_resource
#endif
}
#if defined(NV_DMA_MAP_OPS_HAS_MAP_PHYS)
return (ops->map_phys != NULL);
#else
return (ops->map_resource != NULL);
#endif
}
/* DMA-map a peer device's C2C aperture for peer access. */

View File

@@ -468,9 +468,28 @@ nv_dma_buf_dup_mem_handles(
return NV_OK;
failed:
nv_dma_buf_undup_mem_handles_unlocked(sp, params->index, count, priv);
if (!priv->acquire_release_all_gpu_lock_on_dup)
{
//
// Undup requires taking all-GPUs lock.
// So if single GPU lock was taken,
// release it first so all-GPUs lock can be taken in
// nv_dma_buf_undup_mem_handles().
//
nv_dma_buf_release_gpu_lock(sp, priv);
nv_dma_buf_release_gpu_lock(sp, priv);
nv_dma_buf_undup_mem_handles(sp, params->index, count, priv);
}
else
{
//
// Here, all-GPUs lock is already taken, so undup the handles under
// the unlocked version of the function and then release the locks.
//
nv_dma_buf_undup_mem_handles_unlocked(sp, params->index, count, priv);
nv_dma_buf_release_gpu_lock(sp, priv);
}
unlock_api_lock:
rm_release_api_lock(sp);

View File

@@ -72,7 +72,7 @@ nvidia_vma_open(struct vm_area_struct *vma)
if (at != NULL)
{
NV_ATOMIC_INC(at->usage_count);
atomic64_inc(&at->usage_count);
NV_PRINT_AT(NV_DBG_MEMINFO, at);
}
@@ -414,7 +414,7 @@ static int nvidia_mmap_sysmem(
int ret = 0;
unsigned long start = 0;
NV_ATOMIC_INC(at->usage_count);
atomic64_inc(&at->usage_count);
start = vma->vm_start;
for (j = page_index; j < (page_index + pages); j++)
@@ -450,7 +450,7 @@ static int nvidia_mmap_sysmem(
if (ret)
{
NV_ATOMIC_DEC(at->usage_count);
atomic64_dec(&at->usage_count);
nv_printf(NV_DBG_ERRORS,
"NVRM: Userspace mapping creation failed [%d]!\n", ret);
return -EAGAIN;

View File

@@ -244,7 +244,11 @@ static int nv_resize_pcie_bars(struct pci_dev *pci_dev) {
resize:
/* Attempt to resize BAR1 to the largest supported size */
#if defined(NV_PCI_RESIZE_RESOURCE_HAS_EXCLUDE_BARS_ARG)
r = pci_resize_resource(pci_dev, NV_GPU_BAR1, requested_size, 0);
#else
r = pci_resize_resource(pci_dev, NV_GPU_BAR1, requested_size);
#endif
if (r) {
if (r == -ENOSPC)
@@ -1687,11 +1691,6 @@ nv_pci_probe
nv_printf(NV_DBG_SETUP, "NVRM: probing 0x%x 0x%x, class 0x%x\n",
pci_dev->vendor, pci_dev->device, pci_dev->class);
if (nv_kmem_cache_alloc_stack(&sp) != 0)
{
return -1;
}
#ifdef NV_PCI_SRIOV_SUPPORT
if (pci_dev->is_virtfn)
{
@@ -1707,21 +1706,25 @@ nv_pci_probe
"since IOMMU is not present on the system.\n",
NV_PCI_DOMAIN_NUMBER(pci_dev), NV_PCI_BUS_NUMBER(pci_dev),
NV_PCI_SLOT_NUMBER(pci_dev), PCI_FUNC(pci_dev->devfn));
goto failed;
return -1;
}
nv_kmem_cache_free_stack(sp);
return 0;
#else
nv_printf(NV_DBG_ERRORS, "NVRM: Ignoring probe for VF %04x:%02x:%02x.%x ",
NV_PCI_DOMAIN_NUMBER(pci_dev), NV_PCI_BUS_NUMBER(pci_dev),
NV_PCI_SLOT_NUMBER(pci_dev), PCI_FUNC(pci_dev->devfn));
goto failed;
return -1;
#endif /* NV_VGPU_KVM_BUILD */
}
#endif /* NV_PCI_SRIOV_SUPPORT */
if (nv_kmem_cache_alloc_stack(&sp) != 0)
{
return -1;
}
if (!rm_wait_for_bar_firewall(
sp,
NV_PCI_DOMAIN_NUMBER(pci_dev),
@@ -2178,7 +2181,7 @@ nv_pci_remove(struct pci_dev *pci_dev)
* For eGPU, fall off the bus along with clients active is a valid scenario.
* Hence skipping the sanity check for eGPU.
*/
if ((NV_ATOMIC_READ(nvl->usage_count) != 0) && !(nv->is_external_gpu))
if ((atomic64_read(&nvl->usage_count) != 0) && !(nv->is_external_gpu))
{
nv_printf(NV_DBG_ERRORS,
"NVRM: Attempting to remove device %04x:%02x:%02x.%x with non-zero usage count!\n",
@@ -2189,7 +2192,7 @@ nv_pci_remove(struct pci_dev *pci_dev)
* We can't return from this function without corrupting state, so we wait for
* the usage count to go to zero.
*/
while (NV_ATOMIC_READ(nvl->usage_count) != 0)
while (atomic64_read(&nvl->usage_count) != 0)
{
/*
@@ -2267,7 +2270,7 @@ nv_pci_remove(struct pci_dev *pci_dev)
nvl->sysfs_config_file = NULL;
}
if (NV_ATOMIC_READ(nvl->usage_count) == 0)
if (atomic64_read(&nvl->usage_count) == 0)
{
nv_lock_destroy_locks(sp, nv);
}
@@ -2283,7 +2286,7 @@ nv_pci_remove(struct pci_dev *pci_dev)
num_nv_devices--;
if (NV_ATOMIC_READ(nvl->usage_count) == 0)
if (atomic64_read(&nvl->usage_count) == 0)
{
NV_PCI_DISABLE_DEVICE(pci_dev);
NV_KFREE(nvl, sizeof(nv_linux_state_t));

View File

@@ -890,7 +890,7 @@ nv_procfs_close_unbind_lock(
down(&nvl->ldata_lock);
if ((value == 1) && !(nv->flags & NV_FLAG_UNBIND_LOCK))
{
if (NV_ATOMIC_READ(nvl->usage_count) == 0)
if (atomic64_read(&nvl->usage_count) == 0)
rm_unbind_lock(sp, nv);
if (nv->flags & NV_FLAG_UNBIND_LOCK)

View File

@@ -419,7 +419,7 @@ nv_alloc_t *nvos_create_alloc(
return NULL;
}
NV_ATOMIC_SET(at->usage_count, 0);
atomic64_set(&at->usage_count, 0);
at->pid = os_get_current_process();
at->dev = dev;
@@ -434,7 +434,7 @@ int nvos_free_alloc(
if (at == NULL)
return -1;
if (NV_ATOMIC_READ(at->usage_count))
if (atomic64_read(&at->usage_count))
return 1;
kvfree(at->page_table);
@@ -1656,13 +1656,10 @@ static int nv_open_device(nv_state_t *nv, nvidia_stack_t *sp)
return -ENODEV;
}
if (unlikely(NV_ATOMIC_READ(nvl->usage_count) >= NV_S32_MAX))
return -EMFILE;
if ( ! (nv->flags & NV_FLAG_OPEN))
{
/* Sanity check: !NV_FLAG_OPEN requires usage_count == 0 */
if (NV_ATOMIC_READ(nvl->usage_count) != 0)
if (atomic64_read(&nvl->usage_count) != 0)
{
NV_DEV_PRINTF(NV_DBG_ERRORS, nv,
"Minor device %u is referenced without being open!\n",
@@ -1684,7 +1681,7 @@ static int nv_open_device(nv_state_t *nv, nvidia_stack_t *sp)
nv_assert_not_in_gpu_exclusion_list(sp, nv);
NV_ATOMIC_INC(nvl->usage_count);
atomic64_inc(&nvl->usage_count);
return 0;
}
@@ -2100,7 +2097,7 @@ static void nv_close_device(nv_state_t *nv, nvidia_stack_t *sp)
{
nv_linux_state_t *nvl = NV_GET_NVL_FROM_NV_STATE(nv);
if (NV_ATOMIC_READ(nvl->usage_count) == 0)
if (atomic64_read(&nvl->usage_count) == 0)
{
nv_printf(NV_DBG_ERRORS,
"NVRM: Attempting to close unopened minor device %u!\n",
@@ -2109,7 +2106,7 @@ static void nv_close_device(nv_state_t *nv, nvidia_stack_t *sp)
return;
}
if (NV_ATOMIC_DEC_AND_TEST(nvl->usage_count))
if (atomic64_dec_and_test(&nvl->usage_count))
nv_stop_device(nv, sp);
}
@@ -2154,7 +2151,7 @@ nvidia_close_callback(
nv_close_device(nv, sp);
bRemove = (!NV_IS_DEVICE_IN_SURPRISE_REMOVAL(nv)) &&
(NV_ATOMIC_READ(nvl->usage_count) == 0) &&
(atomic64_read(&nvl->usage_count) == 0) &&
rm_get_device_remove_flag(sp, nv->gpu_id);
nv_free_file_private(nvlfp);
@@ -2173,7 +2170,7 @@ nvidia_close_callback(
* any cleanup related to linux layer locks and nv linux state struct.
* nvidia_pci_remove when scheduled will do necessary cleanup.
*/
if ((NV_ATOMIC_READ(nvl->usage_count) == 0) && nv->removed)
if ((atomic64_read(&nvl->usage_count) == 0) && nv->removed)
{
nv_lock_destroy_locks(sp, nv);
NV_KFREE(nvl, sizeof(nv_linux_state_t));
@@ -2693,7 +2690,7 @@ nvidia_ioctl(
* Only the current client should have an open file
* descriptor for the device, to allow safe offlining.
*/
if (NV_ATOMIC_READ(nvl->usage_count) > 1)
if (atomic64_read(&nvl->usage_count) > 1)
{
status = -EBUSY;
goto unlock;
@@ -3082,12 +3079,12 @@ nvidia_ctl_open(
/* save the nv away in file->private_data */
nvlfp->nvptr = nvl;
if (NV_ATOMIC_READ(nvl->usage_count) == 0)
if (atomic64_read(&nvl->usage_count) == 0)
{
nv->flags |= (NV_FLAG_OPEN | NV_FLAG_CONTROL);
}
NV_ATOMIC_INC(nvl->usage_count);
atomic64_inc(&nvl->usage_count);
up(&nvl->ldata_lock);
return 0;
@@ -3112,7 +3109,7 @@ nvidia_ctl_close(
nv_printf(NV_DBG_INFO, "NVRM: nvidia_ctl_close\n");
down(&nvl->ldata_lock);
if (NV_ATOMIC_DEC_AND_TEST(nvl->usage_count))
if (atomic64_dec_and_test(&nvl->usage_count))
{
nv->flags &= ~NV_FLAG_OPEN;
}
@@ -3275,7 +3272,7 @@ nv_alias_pages(
at->guest_id = guest_id;
*priv_data = at;
NV_ATOMIC_INC(at->usage_count);
atomic64_inc(&at->usage_count);
NV_PRINT_AT(NV_DBG_MEMINFO, at);
@@ -3588,7 +3585,7 @@ NV_STATUS NV_API_CALL nv_register_sgt(
at->order = get_order(at->num_pages * PAGE_SIZE);
NV_ATOMIC_INC(at->usage_count);
atomic64_inc(&at->usage_count);
*priv_data = at;
@@ -3619,7 +3616,7 @@ void NV_API_CALL nv_unregister_sgt(
*import_priv = at->import_priv;
}
if (NV_ATOMIC_DEC_AND_TEST(at->usage_count))
if (atomic64_dec_and_test(&at->usage_count))
{
nvos_free_alloc(at);
}
@@ -3892,7 +3889,7 @@ NV_STATUS NV_API_CALL nv_alloc_pages(
}
*priv_data = at;
NV_ATOMIC_INC(at->usage_count);
atomic64_inc(&at->usage_count);
NV_PRINT_AT(NV_DBG_MEMINFO, at);
@@ -3928,7 +3925,7 @@ NV_STATUS NV_API_CALL nv_free_pages(
* This is described in greater detail in the comments above the
* nvidia_vma_(open|release)() callbacks in nv-mmap.c.
*/
if (!NV_ATOMIC_DEC_AND_TEST(at->usage_count))
if (!atomic64_dec_and_test(&at->usage_count))
return NV_OK;
if (!at->flags.guest && !at->import_sgt)
@@ -3957,7 +3954,7 @@ NvBool nv_lock_init_locks
NV_INIT_MUTEX(&nvl->mmap_lock);
NV_INIT_MUTEX(&nvl->open_q_lock);
NV_ATOMIC_SET(nvl->usage_count, 0);
atomic64_set(&nvl->usage_count, 0);
if (!rm_init_event_locks(sp, nv))
return NV_FALSE;

View File

@@ -141,6 +141,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += icc_get
NV_CONFTEST_FUNCTION_COMPILE_TESTS += devm_of_icc_get
NV_CONFTEST_FUNCTION_COMPILE_TESTS += icc_put
NV_CONFTEST_FUNCTION_COMPILE_TESTS += icc_set_bw
NV_CONFTEST_FUNCTION_COMPILE_TESTS += dma_map_ops_has_map_phys
NV_CONFTEST_FUNCTION_COMPILE_TESTS += dma_buf_ops_has_map
NV_CONFTEST_FUNCTION_COMPILE_TESTS += dma_buf_ops_has_map_atomic
NV_CONFTEST_FUNCTION_COMPILE_TESTS += dma_buf_attachment_has_peer2peer
@@ -159,6 +160,8 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += ioasid_get
NV_CONFTEST_FUNCTION_COMPILE_TESTS += mm_pasid_drop
NV_CONFTEST_FUNCTION_COMPILE_TESTS += iommu_sva_bind_device_has_drvdata_arg
NV_CONFTEST_FUNCTION_COMPILE_TESTS += shrinker_alloc
NV_CONFTEST_FUNCTION_COMPILE_TESTS += vm_flags_set
NV_CONFTEST_FUNCTION_COMPILE_TESTS += vma_flags_set_word
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_gpl_sme_active
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_swiotlb_map_sg_attrs
@@ -206,7 +209,6 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += remove_memory_has_nid_arg
NV_CONFTEST_TYPE_COMPILE_TESTS += add_memory_driver_managed_has_mhp_flags_arg
NV_CONFTEST_TYPE_COMPILE_TESTS += num_registered_fb
NV_CONFTEST_TYPE_COMPILE_TESTS += pci_driver_has_driver_managed_dma
NV_CONFTEST_TYPE_COMPILE_TESTS += vm_area_struct_has_const_vm_flags
NV_CONFTEST_TYPE_COMPILE_TESTS += memory_failure_queue_has_trapno_arg
NV_CONFTEST_TYPE_COMPILE_TESTS += foll_longterm_present
NV_CONFTEST_TYPE_COMPILE_TESTS += bus_type_has_iommu_ops
@@ -220,6 +222,7 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += devfreq_has_suspend_freq
NV_CONFTEST_TYPE_COMPILE_TESTS += has_enum_pidtype_tgid
NV_CONFTEST_TYPE_COMPILE_TESTS += bpmp_mrq_has_strap_set
NV_CONFTEST_TYPE_COMPILE_TESTS += register_shrinker_has_format_arg
NV_CONFTEST_TYPE_COMPILE_TESTS += pci_resize_resource_has_exclude_bars_arg
NV_CONFTEST_GENERIC_COMPILE_TESTS += dom0_kernel_present
NV_CONFTEST_GENERIC_COMPILE_TESTS += nvidia_vgpu_kvm_build

View File

@@ -371,7 +371,7 @@ NvBool NV_API_CALL os_semaphore_may_sleep(void)
NvBool NV_API_CALL os_is_isr(void)
{
return (in_irq());
return (nv_in_hardirq());
}
// return TRUE if the caller is the super-user