diff options
Diffstat (limited to 'drivers/hv/connection.c')
-rw-r--r-- | drivers/hv/connection.c | 24 |
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 | */ | ||
243 | static 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); |