diff options
author | Timo Teräs <timo.teras@iki.fi> | 2010-12-15 13:48:09 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-12-16 15:35:15 -0500 |
commit | 4b2f9abea52af3782d349080fca5e189b0693792 (patch) | |
tree | a54b2ca87e97b0dedcd934b4db68af0a8a381329 /drivers/staging | |
parent | bf6506f60c46c8a709df534408cc6d470df657ff (diff) |
staging: hv: convert channel_mgmt.c to not call osd_schedule_callback
The additional abstraction is unneeded.
The three calls are assumed to not be pending simultaneously:
- vmbus_onoffer queues work exactly once when a new channel is
created, the channel is not attached to lists until the work
is executed
- vmbus_onoffer_rescind is received only when the channel is
active it is enough to process the work once
- free_channel is called exactly once when the channel is getting
destroyed; I assumed that vmbus_process_rescind_offer cannot be
pending while free_channel is called
Reviewed-By: Hank Janssen <hjanssen@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/hv/channel_mgmt.c | 52 | ||||
-rw-r--r-- | drivers/staging/hv/channel_mgmt.h | 1 |
2 files changed, 31 insertions, 22 deletions
diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 6f393e7d8e25..d44d5c39f68b 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c | |||
@@ -263,9 +263,11 @@ static struct vmbus_channel *alloc_channel(void) | |||
263 | /* | 263 | /* |
264 | * release_hannel - Release the vmbus channel object itself | 264 | * release_hannel - Release the vmbus channel object itself |
265 | */ | 265 | */ |
266 | static inline void release_channel(void *context) | 266 | static void release_channel(struct work_struct *work) |
267 | { | 267 | { |
268 | struct vmbus_channel *channel = context; | 268 | struct vmbus_channel *channel = container_of(work, |
269 | struct vmbus_channel, | ||
270 | work); | ||
269 | 271 | ||
270 | DPRINT_DBG(VMBUS, "releasing channel (%p)", channel); | 272 | DPRINT_DBG(VMBUS, "releasing channel (%p)", channel); |
271 | destroy_workqueue(channel->controlwq); | 273 | destroy_workqueue(channel->controlwq); |
@@ -286,8 +288,8 @@ void free_channel(struct vmbus_channel *channel) | |||
286 | * workqueue/thread context | 288 | * workqueue/thread context |
287 | * ie we can't destroy ourselves. | 289 | * ie we can't destroy ourselves. |
288 | */ | 290 | */ |
289 | osd_schedule_callback(gVmbusConnection.WorkQueue, release_channel, | 291 | INIT_WORK(&channel->work, release_channel); |
290 | channel); | 292 | queue_work(gVmbusConnection.WorkQueue, &channel->work); |
291 | } | 293 | } |
292 | 294 | ||
293 | 295 | ||
@@ -308,20 +310,37 @@ static void count_hv_channel(void) | |||
308 | spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); | 310 | spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); |
309 | } | 311 | } |
310 | 312 | ||
313 | /* | ||
314 | * vmbus_process_rescind_offer - | ||
315 | * Rescind the offer by initiating a device removal | ||
316 | */ | ||
317 | static void vmbus_process_rescind_offer(struct work_struct *work) | ||
318 | { | ||
319 | struct vmbus_channel *channel = container_of(work, | ||
320 | struct vmbus_channel, | ||
321 | work); | ||
322 | |||
323 | vmbus_child_device_unregister(channel->device_obj); | ||
324 | } | ||
311 | 325 | ||
312 | /* | 326 | /* |
313 | * vmbus_process_offer - Process the offer by creating a channel/device | 327 | * vmbus_process_offer - Process the offer by creating a channel/device |
314 | * associated with this offer | 328 | * associated with this offer |
315 | */ | 329 | */ |
316 | static void vmbus_process_offer(void *context) | 330 | static void vmbus_process_offer(struct work_struct *work) |
317 | { | 331 | { |
318 | struct vmbus_channel *newchannel = context; | 332 | struct vmbus_channel *newchannel = container_of(work, |
333 | struct vmbus_channel, | ||
334 | work); | ||
319 | struct vmbus_channel *channel; | 335 | struct vmbus_channel *channel; |
320 | bool fnew = true; | 336 | bool fnew = true; |
321 | int ret; | 337 | int ret; |
322 | int cnt; | 338 | int cnt; |
323 | unsigned long flags; | 339 | unsigned long flags; |
324 | 340 | ||
341 | /* The next possible work is rescind handling */ | ||
342 | INIT_WORK(&newchannel->work, vmbus_process_rescind_offer); | ||
343 | |||
325 | /* Make sure this is a new offer */ | 344 | /* Make sure this is a new offer */ |
326 | spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); | 345 | spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); |
327 | 346 | ||
@@ -406,17 +425,6 @@ static void vmbus_process_offer(void *context) | |||
406 | } | 425 | } |
407 | 426 | ||
408 | /* | 427 | /* |
409 | * vmbus_process_rescind_offer - | ||
410 | * Rescind the offer by initiating a device removal | ||
411 | */ | ||
412 | static void vmbus_process_rescind_offer(void *context) | ||
413 | { | ||
414 | struct vmbus_channel *channel = context; | ||
415 | |||
416 | vmbus_child_device_unregister(channel->device_obj); | ||
417 | } | ||
418 | |||
419 | /* | ||
420 | * vmbus_onoffer - Handler for channel offers from vmbus in parent partition. | 428 | * vmbus_onoffer - Handler for channel offers from vmbus in parent partition. |
421 | * | 429 | * |
422 | * We ignore all offers except network and storage offers. For each network and | 430 | * We ignore all offers except network and storage offers. For each network and |
@@ -490,8 +498,8 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) | |||
490 | newchannel->monitor_bit = (u8)offer->monitorid % 32; | 498 | newchannel->monitor_bit = (u8)offer->monitorid % 32; |
491 | 499 | ||
492 | /* TODO: Make sure the offer comes from our parent partition */ | 500 | /* TODO: Make sure the offer comes from our parent partition */ |
493 | osd_schedule_callback(newchannel->controlwq, vmbus_process_offer, | 501 | INIT_WORK(&newchannel->work, vmbus_process_offer); |
494 | newchannel); | 502 | queue_work(newchannel->controlwq, &newchannel->work); |
495 | } | 503 | } |
496 | 504 | ||
497 | /* | 505 | /* |
@@ -512,9 +520,9 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) | |||
512 | return; | 520 | return; |
513 | } | 521 | } |
514 | 522 | ||
515 | osd_schedule_callback(channel->controlwq, | 523 | /* work is initialized for vmbus_process_rescind_offer() from |
516 | vmbus_process_rescind_offer, | 524 | * vmbus_process_offer() where the channel got created */ |
517 | channel); | 525 | queue_work(channel->controlwq, &channel->work); |
518 | } | 526 | } |
519 | 527 | ||
520 | /* | 528 | /* |
diff --git a/drivers/staging/hv/channel_mgmt.h b/drivers/staging/hv/channel_mgmt.h index 12f30aff152d..de6b2a0ebf70 100644 --- a/drivers/staging/hv/channel_mgmt.h +++ b/drivers/staging/hv/channel_mgmt.h | |||
@@ -231,6 +231,7 @@ struct vmbus_channel { | |||
231 | struct hv_device *device_obj; | 231 | struct hv_device *device_obj; |
232 | 232 | ||
233 | struct timer_list poll_timer; /* SA-111 workaround */ | 233 | struct timer_list poll_timer; /* SA-111 workaround */ |
234 | struct work_struct work; | ||
234 | 235 | ||
235 | enum vmbus_channel_state state; | 236 | enum vmbus_channel_state state; |
236 | 237 | ||