3131#define OVER_SUBSCRIPTION_PROCESS_COUNT (1 << 0)
3232#define OVER_SUBSCRIPTION_COMPUTE_QUEUE_COUNT (1 << 1)
3333#define OVER_SUBSCRIPTION_GWS_QUEUE_COUNT (1 << 2)
34+ #define OVER_SUBSCRIPTION_XNACK_CONFLICT (1 << 3)
3435
3536static inline void inc_wptr (unsigned int * wptr , unsigned int increment_bytes ,
3637 unsigned int buffer_size_bytes )
@@ -44,7 +45,8 @@ static inline void inc_wptr(unsigned int *wptr, unsigned int increment_bytes,
4445
4546static void pm_calc_rlib_size (struct packet_manager * pm ,
4647 unsigned int * rlib_size ,
47- int * over_subscription )
48+ int * over_subscription ,
49+ int xnack_conflict )
4850{
4951 unsigned int process_count , queue_count , compute_queue_count , gws_queue_count ;
5052 unsigned int map_queue_size ;
@@ -73,6 +75,8 @@ static void pm_calc_rlib_size(struct packet_manager *pm,
7375 * over_subscription |= OVER_SUBSCRIPTION_COMPUTE_QUEUE_COUNT ;
7476 if (gws_queue_count > 1 )
7577 * over_subscription |= OVER_SUBSCRIPTION_GWS_QUEUE_COUNT ;
78+ if (xnack_conflict && (node -> adev -> gmc .xnack_flags & AMDGPU_GMC_XNACK_FLAG_CHAIN ))
79+ * over_subscription |= OVER_SUBSCRIPTION_XNACK_CONFLICT ;
7680
7781 if (* over_subscription )
7882 dev_dbg (dev , "Over subscribed runlist\n" );
@@ -96,7 +100,8 @@ static int pm_allocate_runlist_ib(struct packet_manager *pm,
96100 unsigned int * * rl_buffer ,
97101 uint64_t * rl_gpu_buffer ,
98102 unsigned int * rl_buffer_size ,
99- int * is_over_subscription )
103+ int * is_over_subscription ,
104+ int xnack_conflict )
100105{
101106 struct kfd_node * node = pm -> dqm -> dev ;
102107 struct device * dev = node -> adev -> dev ;
@@ -105,7 +110,8 @@ static int pm_allocate_runlist_ib(struct packet_manager *pm,
105110 if (WARN_ON (pm -> allocated ))
106111 return - EINVAL ;
107112
108- pm_calc_rlib_size (pm , rl_buffer_size , is_over_subscription );
113+ pm_calc_rlib_size (pm , rl_buffer_size , is_over_subscription ,
114+ xnack_conflict );
109115
110116 mutex_lock (& pm -> lock );
111117
@@ -142,11 +148,27 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
142148 struct queue * q ;
143149 struct kernel_queue * kq ;
144150 int is_over_subscription ;
151+ int xnack_enabled = -1 ;
152+ bool xnack_conflict = 0 ;
145153
146154 rl_wptr = retval = processes_mapped = 0 ;
147155
156+ /* Check if processes set different xnack modes */
157+ list_for_each_entry (cur , queues , list ) {
158+ qpd = cur -> qpd ;
159+ if (xnack_enabled < 0 )
160+ /* First process */
161+ xnack_enabled = qpd -> pqm -> process -> xnack_enabled ;
162+ else if (qpd -> pqm -> process -> xnack_enabled != xnack_enabled ) {
163+ /* Found a process with a different xnack mode */
164+ xnack_conflict = 1 ;
165+ break ;
166+ }
167+ }
168+
148169 retval = pm_allocate_runlist_ib (pm , & rl_buffer , rl_gpu_addr ,
149- & alloc_size_bytes , & is_over_subscription );
170+ & alloc_size_bytes , & is_over_subscription ,
171+ xnack_conflict );
150172 if (retval )
151173 return retval ;
152174
@@ -156,9 +178,13 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
156178 dev_dbg (dev , "Building runlist ib process count: %d queues count %d\n" ,
157179 pm -> dqm -> processes_count , pm -> dqm -> active_queue_count );
158180
181+ build_runlist_ib :
159182 /* build the run list ib packet */
160183 list_for_each_entry (cur , queues , list ) {
161184 qpd = cur -> qpd ;
185+ /* group processes with the same xnack mode together */
186+ if (qpd -> pqm -> process -> xnack_enabled != xnack_enabled )
187+ continue ;
162188 /* build map process packet */
163189 if (processes_mapped >= pm -> dqm -> processes_count ) {
164190 dev_dbg (dev , "Not enough space left in runlist IB\n" );
@@ -215,18 +241,26 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
215241 alloc_size_bytes );
216242 }
217243 }
244+ if (xnack_conflict ) {
245+ /* pick up processes with the other xnack mode */
246+ xnack_enabled = !xnack_enabled ;
247+ xnack_conflict = 0 ;
248+ goto build_runlist_ib ;
249+ }
218250
219251 dev_dbg (dev , "Finished map process and queues to runlist\n" );
220252
221253 if (is_over_subscription ) {
222254 if (!pm -> is_over_subscription )
223- dev_warn (dev , "Runlist is getting oversubscribed due to%s%s%s. Expect reduced ROCm performance.\n" ,
224- is_over_subscription & OVER_SUBSCRIPTION_PROCESS_COUNT ?
225- " too many processes." : "" ,
226- is_over_subscription & OVER_SUBSCRIPTION_COMPUTE_QUEUE_COUNT ?
227- " too many queues." : "" ,
228- is_over_subscription & OVER_SUBSCRIPTION_GWS_QUEUE_COUNT ?
229- " multiple processes using cooperative launch." : "" );
255+ dev_warn (dev , "Runlist is getting oversubscribed due to%s%s%s%s. Expect reduced ROCm performance.\n" ,
256+ is_over_subscription & OVER_SUBSCRIPTION_PROCESS_COUNT ?
257+ " too many processes" : "" ,
258+ is_over_subscription & OVER_SUBSCRIPTION_COMPUTE_QUEUE_COUNT ?
259+ " too many queues" : "" ,
260+ is_over_subscription & OVER_SUBSCRIPTION_GWS_QUEUE_COUNT ?
261+ " multiple processes using cooperative launch" : "" ,
262+ is_over_subscription & OVER_SUBSCRIPTION_XNACK_CONFLICT ?
263+ " xnack on/off processes mixed on gfx9" : "" );
230264
231265 retval = pm -> pmf -> runlist (pm , & rl_buffer [rl_wptr ],
232266 * rl_gpu_addr ,
0 commit comments