Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Drivers: hv: vmbus: distribute subchannels among all vcpus

Primary channels are distributed evenly across all vcpus we have. When the host
asks us to create subchannels it usually makes us num_cpus-1 offers and we are
supposed to distribute the work evenly among the channel itself and all its
subchannels. Make sure they are all assigned to different vcpus.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Vitaly Kuznetsov and committed by
Greg Kroah-Hartman
ce59fec8 f38e7dd7

+28 -1
+28 -1
drivers/hv/channel_mgmt.c
··· 387 387 int i; 388 388 bool perf_chn = false; 389 389 u32 max_cpus = num_online_cpus(); 390 + struct vmbus_channel *primary = channel->primary_channel, *prev; 391 + unsigned long flags; 390 392 391 393 for (i = IDE; i < MAX_PERF_CHN; i++) { 392 394 if (!memcmp(type_guid->b, hp_devs[i].guid, ··· 409 407 channel->target_vp = 0; 410 408 return; 411 409 } 412 - cur_cpu = (++next_vp % max_cpus); 410 + 411 + /* 412 + * Primary channels are distributed evenly across all vcpus we have. 413 + * When the host asks us to create subchannels it usually makes us 414 + * num_cpus-1 offers and we are supposed to distribute the work evenly 415 + * among the channel itself and all its subchannels. Make sure they are 416 + * all assigned to different vcpus. 417 + */ 418 + if (!primary) 419 + cur_cpu = (++next_vp % max_cpus); 420 + else { 421 + /* 422 + * Let's assign the first subchannel of a channel to the 423 + * primary->target_cpu+1 and all the subsequent channels to 424 + * the prev->target_cpu+1. 425 + */ 426 + spin_lock_irqsave(&primary->lock, flags); 427 + if (primary->num_sc == 1) 428 + cur_cpu = (primary->target_cpu + 1) % max_cpus; 429 + else { 430 + prev = list_prev_entry(channel, sc_list); 431 + cur_cpu = (prev->target_cpu + 1) % max_cpus; 432 + } 433 + spin_unlock_irqrestore(&primary->lock, flags); 434 + } 435 + 413 436 channel->target_cpu = cur_cpu; 414 437 channel->target_vp = hv_context.vp_index[cur_cpu]; 415 438 }