diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 16:57:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 16:57:13 -0500 |
commit | 7ed214ac2095f561a94335ca672b6c42a1ea40ff (patch) | |
tree | da41901bff1d0d8d61170bf362384fdc61deb3ab /drivers/hv/channel_mgmt.c | |
parent | 21eaab6d19ed43e82ed39c8deb7f192134fb4a0e (diff) | |
parent | 29e5507ae4ab34397f538f06b7070c81a4e4a2bf (diff) |
Merge tag 'char-misc-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver patches from Greg Kroah-Hartman:
"Here's the big char/misc driver patches for 3.9-rc1.
Nothing major here, just lots of different driver updates (mei,
hyperv, ipack, extcon, vmci, etc.).
All of these have been in the linux-next tree for a while."
* tag 'char-misc-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (209 commits)
w1: w1_therm: Add force-pullup option for "broken" sensors
w1: ds2482: Added 1-Wire pull-up support to the driver
vme: add missing put_device() after device_register() fails
extcon: max8997: Use workqueue to check cable state after completing boot of platform
extcon: max8997: Set default UART/USB path on probe
extcon: max8997: Consolidate duplicate code for checking ADC/CHG cable type
extcon: max8997: Set default of ADC debounce time during initialization
extcon: max8997: Remove duplicate code related to set H/W line path
extcon: max8997: Move defined constant to header file
extcon: max77693: Make max77693_extcon_cable static
extcon: max8997: Remove unreachable code
extcon: max8997: Make max8997_extcon_cable static
extcon: max77693: Remove unnecessary goto statement to improve readability
extcon: max77693: Convert to devm_input_allocate_device()
extcon: gpio: Rename filename of extcon-gpio.c according to kernel naming style
CREDITS: update email and address of Harald Hoyer
extcon: arizona: Use MICDET for final microphone identification
extcon: arizona: Always take the first HPDET reading as the final one
extcon: arizona: Clear _trig_sts bits after jack detection
extcon: arizona: Don't HPDET magic when headphones are enabled
...
Diffstat (limited to 'drivers/hv/channel_mgmt.c')
-rw-r--r-- | drivers/hv/channel_mgmt.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 2f84c5cff8d4..53a8600162a5 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c | |||
@@ -257,6 +257,70 @@ static void vmbus_process_offer(struct work_struct *work) | |||
257 | } | 257 | } |
258 | } | 258 | } |
259 | 259 | ||
260 | enum { | ||
261 | IDE = 0, | ||
262 | SCSI, | ||
263 | NIC, | ||
264 | MAX_PERF_CHN, | ||
265 | }; | ||
266 | |||
267 | /* | ||
268 | * This is an array of device_ids (device types) that are performance critical. | ||
269 | * We attempt to distribute the interrupt load for these devices across | ||
270 | * all available CPUs. | ||
271 | */ | ||
272 | static const struct hv_vmbus_device_id hp_devs[] = { | ||
273 | /* IDE */ | ||
274 | { HV_IDE_GUID, }, | ||
275 | /* Storage - SCSI */ | ||
276 | { HV_SCSI_GUID, }, | ||
277 | /* Network */ | ||
278 | { HV_NIC_GUID, }, | ||
279 | }; | ||
280 | |||
281 | |||
282 | /* | ||
283 | * We use this state to statically distribute the channel interrupt load. | ||
284 | */ | ||
285 | static u32 next_vp; | ||
286 | |||
287 | /* | ||
288 | * Starting with Win8, we can statically distribute the incoming | ||
289 | * channel interrupt load by binding a channel to VCPU. We | ||
290 | * implement here a simple round robin scheme for distributing | ||
291 | * the interrupt load. | ||
292 | * We will bind channels that are not performance critical to cpu 0 and | ||
293 | * performance critical channels (IDE, SCSI and Network) will be uniformly | ||
294 | * distributed across all available CPUs. | ||
295 | */ | ||
296 | static u32 get_vp_index(uuid_le *type_guid) | ||
297 | { | ||
298 | u32 cur_cpu; | ||
299 | int i; | ||
300 | bool perf_chn = false; | ||
301 | u32 max_cpus = num_online_cpus(); | ||
302 | |||
303 | for (i = IDE; i < MAX_PERF_CHN; i++) { | ||
304 | if (!memcmp(type_guid->b, hp_devs[i].guid, | ||
305 | sizeof(uuid_le))) { | ||
306 | perf_chn = true; | ||
307 | break; | ||
308 | } | ||
309 | } | ||
310 | if ((vmbus_proto_version == VERSION_WS2008) || | ||
311 | (vmbus_proto_version == VERSION_WIN7) || (!perf_chn)) { | ||
312 | /* | ||
313 | * Prior to win8, all channel interrupts are | ||
314 | * delivered on cpu 0. | ||
315 | * Also if the channel is not a performance critical | ||
316 | * channel, bind it to cpu 0. | ||
317 | */ | ||
318 | return 0; | ||
319 | } | ||
320 | cur_cpu = (++next_vp % max_cpus); | ||
321 | return 0; | ||
322 | } | ||
323 | |||
260 | /* | 324 | /* |
261 | * vmbus_onoffer - Handler for channel offers from vmbus in parent partition. | 325 | * vmbus_onoffer - Handler for channel offers from vmbus in parent partition. |
262 | * | 326 | * |
@@ -275,6 +339,35 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) | |||
275 | return; | 339 | return; |
276 | } | 340 | } |
277 | 341 | ||
342 | /* | ||
343 | * By default we setup state to enable batched | ||
344 | * reading. A specific service can choose to | ||
345 | * disable this prior to opening the channel. | ||
346 | */ | ||
347 | newchannel->batched_reading = true; | ||
348 | |||
349 | /* | ||
350 | * Setup state for signalling the host. | ||
351 | */ | ||
352 | newchannel->sig_event = (struct hv_input_signal_event *) | ||
353 | (ALIGN((unsigned long) | ||
354 | &newchannel->sig_buf, | ||
355 | HV_HYPERCALL_PARAM_ALIGN)); | ||
356 | |||
357 | newchannel->sig_event->connectionid.asu32 = 0; | ||
358 | newchannel->sig_event->connectionid.u.id = VMBUS_EVENT_CONNECTION_ID; | ||
359 | newchannel->sig_event->flag_number = 0; | ||
360 | newchannel->sig_event->rsvdz = 0; | ||
361 | |||
362 | if (vmbus_proto_version != VERSION_WS2008) { | ||
363 | newchannel->is_dedicated_interrupt = | ||
364 | (offer->is_dedicated_interrupt != 0); | ||
365 | newchannel->sig_event->connectionid.u.id = | ||
366 | offer->connection_id; | ||
367 | } | ||
368 | |||
369 | newchannel->target_vp = get_vp_index(&offer->offer.if_type); | ||
370 | |||
278 | memcpy(&newchannel->offermsg, offer, | 371 | memcpy(&newchannel->offermsg, offer, |
279 | sizeof(struct vmbus_channel_offer_channel)); | 372 | sizeof(struct vmbus_channel_offer_channel)); |
280 | newchannel->monitor_grp = (u8)offer->monitorid / 32; | 373 | newchannel->monitor_grp = (u8)offer->monitorid / 32; |