aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hv/connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hv/connection.c')
-rw-r--r--drivers/hv/connection.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index df2363ea017f..7f10c151632a 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -234,6 +234,28 @@ cleanup:
234 return ret; 234 return ret;
235} 235}
236 236
237/*
238 * Map the given relid to the corresponding channel based on the
239 * per-cpu list of channels that have been affinitized to this CPU.
240 * This will be used in the channel callback path as we can do this
241 * mapping in a lock-free fashion.
242 */
243static struct vmbus_channel *pcpu_relid2channel(u32 relid)
244{
245 struct vmbus_channel *channel;
246 struct vmbus_channel *found_channel = NULL;
247 int cpu = smp_processor_id();
248 struct list_head *pcpu_head = &hv_context.percpu_list[cpu];
249
250 list_for_each_entry(channel, pcpu_head, percpu_list) {
251 if (channel->offermsg.child_relid == relid) {
252 found_channel = channel;
253 break;
254 }
255 }
256
257 return found_channel;
258}
237 259
238/* 260/*
239 * relid2channel - Get the channel object given its 261 * relid2channel - Get the channel object given its
@@ -285,7 +307,7 @@ static void process_chn_event(u32 relid)
285 * Find the channel based on this relid and invokes the 307 * Find the channel based on this relid and invokes the
286 * channel callback to process the event 308 * channel callback to process the event
287 */ 309 */
288 channel = relid2channel(relid); 310 channel = pcpu_relid2channel(relid);
289 311
290 if (!channel) { 312 if (!channel) {
291 pr_err("channel not found for relid - %u\n", relid); 313 pr_err("channel not found for relid - %u\n", relid);