/* AFS common types * * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #ifndef AFS_H #define AFS_H #include #define AFS_MAXCELLNAME 64 /* maximum length of a cell name */ #define AFS_MAXVOLNAME 64 /* maximum length of a volume name */ #define AFSNAMEMAX 256 /* maximum length of a filename plus NUL */ #define AFSPATHMAX 1024 /* maximum length of a pathname plus NUL */ #define AFSOPAQUEMAX 1024 /* maximum length of an opaque field */ typedef unsigned afs_volid_t; typedef unsigned afs_vnodeid_t; typedef unsigned long long afs_dataversion_t; typedef enum { AFSVL_RWVOL, /* read/write volume */ AFSVL_ROVOL, /* read-only volume */ AFSVL_BACKVOL, /* backup volume */ } __attribute__((packed)) afs_voltype_t; typedef enum { AFS_FTYPE_INVALID = 0, AFS_FTYPE_FILE = 1, AFS_FTYPE_DIR = 2, AFS_FTYPE_SYMLINK = 3, } afs_file_type_t; typedef enum { AFS_LOCK_READ = 0, /* read lock request */ AFS_LOCK_WRITE = 1, /* write lock request */ } afs_lock_type_t; #define AFS_LOCKWAIT (5 * 60) /* time until a lock times out (seconds) */ /* * AFS file identifier */ struct afs_fid { afs_volid_t vid; /* volume ID */ afs_vnodeid_t vnode; /* file index within volume */ unsigned unique; /* unique ID number (file index version) */ }; /* * AFS callback notification */ typedef enum { AFSCM_CB_UNTYPED = 0, /* no type set on CB break */ AFSCM_CB_EXCLUSIVE = 1, /* CB exclusive to CM [not implemented] */ AFSCM_CB_SHARED = 2, /* CB shared by other CM's */ AFSCM_CB_DROPPED = 3, /* CB promise cancelled by file server */ } afs_callback_type_t; struct afs_callback { struct afs_fid fid; /* file identifier */ unsigned version; /* callback version */ unsigned expiry; /* time at which expires */ afs_callback_type_t type; /* type of callback */ }; #define AFSCBMAX 50 /* maximum callbacks transferred per bulk op */ /* * AFS volume information */ struct afs_volume_info { afs_volid_t vid; /* volume ID */ afs_voltype_t type; /* type of this volume */ afs_volid_t type_vids[5]; /* volume ID's for possible types for this vol */ /* list of fileservers serving this volume */ size_t nservers; /* number of entries used in servers[] */ struct { struct in_addr addr; /* fileserver address */ } servers[8]; }; /* * AFS security ACE access mask */ typedef u32 afs_access_t; #define AFS_ACE_READ 0x00000001U /* - permission to read a file/dir */ #define AFS_ACE_WRITE 0x00000002U /* - permission to write/chmod a file */ #define AFS_ACE_INSERT 0x00000004U /* - permission to create dirent in a dir */ #define AFS_ACE_LOOKUP 0x00000008U /* - permission to lookup a file/dir in a dir */ #define AFS_ACE_DELETE 0x00000010U /* - permission to delete a dirent from a dir */ #define AFS_ACE_LOCK 0x00000020U /* - permission to lock a file */ #define AFS_ACE_ADMINISTER 0x00000040U /* - permission to change ACL */ #define AFS_ACE_USER_A 0x01000000U /* - 'A' user-defined permission */ #define AFS_ACE_USER_B 0x02000000U /* - 'B' user-defined permission */ #define AFS_ACE_USER_C 0x04000000U /* - 'C' user-defined permission */ #define AFS_ACE_USER_D 0x08000000U /* - 'D' user-defined permission */ #define AFS_ACE_USER_E 0x10000000U /* - 'E' user-defined permission */ #define AFS_ACE_USER_F 0x20000000U /* - 'F' user-defined permission */ #define AFS_ACE_USER_G 0x40000000U /* - 'G' user-defined permission */ #define AFS_ACE_USER_H 0x80000000U /* - 'H' user-defined permission */ /* * AFS file status information */ struct afs_file_status { unsigned if_version; /* interface version */ #define AFS_FSTATUS_VERSION 1 afs_file_type_t type; /* file type */ unsigned nlink; /* link count */ u64 size; /* file size */ afs_dataversion_t data_version; /* current data version */ u32 author; /* author ID */ kuid_t owner; /* owner ID */ kgid_t group; /* group ID */ afs_access_t caller_access; /* access rights for authenticated caller */ afs_access_t anon_access; /* access rights for unauthenticated caller */ umode_t mode; /* UNIX mode */ struct afs_fid parent; /* parent dir ID for non-dirs only */ time_t mtime_client; /* last time client changed data */ time_t mtime_server; /* last time server changed data */ s32 lock_count; /* file lock count (0=UNLK -1=WRLCK +ve=#RDLCK */ }; /* * AFS file status change request */ #define AFS_SET_MTIME 0x01 /* set the mtime */ #define AFS_SET_OWNER 0x02 /* set the owner ID */ #define AFS_SET_GROUP 0x04 /* set the group ID (unsupported?) */ #define AFS_SET_MODE 0x08 /* set the UNIX mode */ #define AFS_SET_SEG_SIZE 0x10 /* set the segment size (unsupported) */ /* * AFS volume synchronisation information */ struct afs_volsync { time_t creation; /* volume creation time */ }; /* * AFS volume status record */ struct afs_volume_status { u32 vid; /* volume ID */ u32 parent_id; /* parent volume ID */ u8 online; /* true if volume currently online and available */ u8 in_service; /* true if volume currently in service */ u8 blessed; /* same as in_service */ u8 needs_salvage; /* true if consistency checking required */ u32 type; /* volume type (afs_voltype_t) */ u32 min_quota; /* minimum space set aside (blocks) */ u32 max_quota; /* maximum space this volume may occupy (blocks) */ u32 blocks_in_use; /* space this volume currently occupies (blocks) */ u32 part_blocks_avail; /* space available in volume's partition */ u32 part_max_blocks; /* size of volume's partition */ }; #define AFS_BLOCK_SIZE 1024 #endif /* AFS_H */ 6d79d4c6529a5f7b9206e405'>2c5d9555d6d937966d79d4c6529a5f7b9206e405 (diff)
drm/i915: Check for NULL i915_vma in intel_unpin_fb_obj()
I've seen this trigger twice now, where the i915_gem_object_to_ggtt() call in intel_unpin_fb_obj() returns NULL, resulting in an oops immediately afterwards as the (inlined) call to i915_vma_unpin_fence() tries to dereference it. It seems to be some race condition where the object is going away at shutdown time, since both times happened when shutting down the X server. The call chains were different: - VT ioctl(KDSETMODE, KD_TEXT): intel_cleanup_plane_fb+0x5b/0xa0 [i915] drm_atomic_helper_cleanup_planes+0x6f/0x90 [drm_kms_helper] intel_atomic_commit_tail+0x749/0xfe0 [i915] intel_atomic_commit+0x3cb/0x4f0 [i915] drm_atomic_commit+0x4b/0x50 [drm] restore_fbdev_mode+0x14c/0x2a0 [drm_kms_helper] drm_fb_helper_restore_fbdev_mode_unlocked+0x34/0x80 [drm_kms_helper] drm_fb_helper_set_par+0x2d/0x60 [drm_kms_helper] intel_fbdev_set_par+0x18/0x70 [i915] fb_set_var+0x236/0x460 fbcon_blank+0x30f/0x350 do_unblank_screen+0xd2/0x1a0 vt_ioctl+0x507/0x12a0 tty_ioctl+0x355/0xc30 do_vfs_ioctl+0xa3/0x5e0 SyS_ioctl+0x79/0x90 entry_SYSCALL_64_fastpath+0x13/0x94 - i915 unpin_work workqueue: intel_unpin_work_fn+0x58/0x140 [i915] process_one_work+0x1f1/0x480 worker_thread+0x48/0x4d0 kthread+0x101/0x140 and this patch purely papers over the issue by adding a NULL pointer check and a WARN_ON_ONCE() to avoid the oops that would then generally make the machine unresponsive. Other callers of i915_gem_object_to_ggtt() seem to also check for the returned pointer being NULL and warn about it, so this clearly has happened before in other places. [ Reported it originally to the i915 developers on Jan 8, applying the ugly workaround on my own now after triggering the problem for the second time with no feedback. This is likely to be the same bug reported as https://bugs.freedesktop.org/show_bug.cgi?id=98829 https://bugs.freedesktop.org/show_bug.cgi?id=99134 which has a patch for the underlying problem, but it hasn't gotten to me, so I'm applying the workaround. ] Cc: Daniel Vetter <daniel.vetter@intel.com> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Imre Deak <imre.deak@intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'tools/objtool')