88#include <linux/aperture.h>
99#include <linux/delay.h>
1010#include <linux/fault-inject.h>
11+ #include <linux/jiffies.h>
1112#include <linux/units.h>
1213
1314#include <drm/drm_atomic_helper.h>
@@ -65,9 +66,13 @@ static int xe_file_open(struct drm_device *dev, struct drm_file *file)
6566{
6667 struct xe_device * xe = to_xe_device (dev );
6768 struct xe_drm_client * client ;
69+ struct xe_user * user ;
6870 struct xe_file * xef ;
6971 int ret = - ENOMEM ;
72+ unsigned long flags ;
73+ unsigned int uid = 0 ;
7074 struct task_struct * task = NULL ;
75+ const struct cred * cred = NULL ;
7176
7277 xef = kzalloc (sizeof (* xef ), GFP_KERNEL );
7378 if (!xef )
@@ -94,11 +99,41 @@ static int xe_file_open(struct drm_device *dev, struct drm_file *file)
9499
95100 task = get_pid_task (rcu_access_pointer (file -> pid ), PIDTYPE_PID );
96101 if (task ) {
102+ cred = get_task_cred (task );
103+ if (cred ) {
104+ uid = cred -> euid .val ;
105+ put_cred (cred );
106+ }
97107 xef -> process_name = kstrdup (task -> comm , GFP_KERNEL );
98108 xef -> pid = task -> pid ;
99109 put_task_struct (task );
100110 }
101111
112+ spin_lock_irqsave (& xe -> work_period .lock , flags );
113+ list_for_each_entry (user , & xe -> work_period .user_list , entry ) {
114+ if (user -> uid == uid ) {
115+ xef -> user = xe_user_get (user );
116+ goto filelist_add ;
117+ }
118+ }
119+ smp_mb ();
120+
121+ user = xe_user_alloc (uid );
122+ if (!user ) {
123+ goto spin_unlk ;
124+ }
125+
126+ user -> last_timestamp_ns = ktime_get_raw_ns ();
127+ list_add (& user -> entry , & xe -> work_period .user_list );
128+ xef -> user = user ;
129+
130+ filelist_add :
131+ spin_lock (& user -> filelist_lock );
132+ list_add (& xef -> user_link , & user -> filelist );
133+ spin_unlock (& user -> filelist_lock );
134+ user -> xe = xe ;
135+ spin_unlk :
136+ spin_unlock_irqrestore (& xe -> work_period .lock , flags );
102137 return 0 ;
103138}
104139
@@ -113,6 +148,9 @@ static void xe_file_destroy(struct kref *ref)
113148
114149 xe_drm_client_put (xef -> client );
115150 kfree (xef -> process_name );
151+
152+ list_del (& xef -> user_link );
153+ xe_user_put (xef -> user );
116154 kfree (xef );
117155}
118156
@@ -231,6 +269,24 @@ static long xe_drm_compat_ioctl(struct file *file, unsigned int cmd, unsigned lo
231269#define xe_drm_compat_ioctl NULL
232270#endif
233271
272+ static void work_period_timer_fn (struct timer_list * timer )
273+ {
274+ struct xe_device * xe = container_of (timer , typeof (* xe ), work_period .timer );
275+ struct xe_user * user ;
276+ unsigned long timeout = 0 ;
277+
278+ spin_lock (& xe -> work_period .lock );
279+ if (!list_empty (& xe -> work_period .user_list )) {
280+ list_for_each_entry (user , & xe -> work_period .user_list , entry ) {
281+ queue_work (xe -> work_period .wq , & user -> work );
282+ }
283+ }
284+ spin_unlock (& xe -> work_period .lock );
285+ timeout = jiffies + msecs_to_jiffies (500 );
286+
287+ mod_timer (timer , timeout );
288+ }
289+
234290static const struct file_operations xe_driver_fops = {
235291 .owner = THIS_MODULE ,
236292 .open = drm_open ,
@@ -291,6 +347,11 @@ static void xe_device_destroy(struct drm_device *dev, void *dummy)
291347 if (xe -> destroy_wq )
292348 destroy_workqueue (xe -> destroy_wq );
293349
350+ if (xe -> work_period .wq )
351+ destroy_workqueue (xe -> work_period .wq );
352+
353+ del_timer (& xe -> work_period .timer );
354+
294355 ttm_device_fini (& xe -> ttm );
295356}
296357
@@ -350,13 +411,22 @@ struct xe_device *xe_device_create(struct pci_dev *pdev,
350411 INIT_LIST_HEAD (& xe -> pinned .external_vram );
351412 INIT_LIST_HEAD (& xe -> pinned .evicted );
352413
414+ spin_lock_init (& xe -> work_period .lock );
415+ INIT_LIST_HEAD (& xe -> work_period .user_list );
416+ timer_setup (& xe -> work_period .timer , work_period_timer_fn , 0 );
417+ xe -> work_period .timer .expires = jiffies + msecs_to_jiffies (1000 );
418+ add_timer (& xe -> work_period .timer );
419+
420+ xe -> work_period .wq = alloc_workqueue ("xe-work-period-wq" , 0 , 0 );
421+
353422 xe -> preempt_fence_wq = alloc_ordered_workqueue ("xe-preempt-fence-wq" ,
354423 WQ_MEM_RECLAIM );
355424 xe -> ordered_wq = alloc_ordered_workqueue ("xe-ordered-wq" , 0 );
356425 xe -> unordered_wq = alloc_workqueue ("xe-unordered-wq" , 0 , 0 );
357426 xe -> destroy_wq = alloc_workqueue ("xe-destroy-wq" , 0 , 0 );
358427 if (!xe -> ordered_wq || !xe -> unordered_wq ||
359- !xe -> preempt_fence_wq || !xe -> destroy_wq ) {
428+ !xe -> preempt_fence_wq || !xe -> destroy_wq ||
429+ !xe -> work_period .wq ) {
360430 /*
361431 * Cleanup done in xe_device_destroy via
362432 * drmm_add_action_or_reset register above
0 commit comments