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

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>

authored by

Timo Teräs and committed by
Greg Kroah-Hartman
4b2f9abe bf6506f6

+31 -22
+30 -22
drivers/staging/hv/channel_mgmt.c
··· 263 263 /* 264 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 272 DPRINT_DBG(VMBUS, "releasing channel (%p)", channel); 271 273 destroy_workqueue(channel->controlwq); ··· 288 286 * workqueue/thread context 289 287 * ie we can't destroy ourselves. 290 288 */ 291 - osd_schedule_callback(gVmbusConnection.WorkQueue, release_channel, 292 - channel); 289 + INIT_WORK(&channel->work, release_channel); 290 + queue_work(gVmbusConnection.WorkQueue, &channel->work); 293 291 } 294 292 295 293 ··· 310 308 spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); 311 309 } 312 310 311 + /* 312 + * vmbus_process_rescind_offer - 313 + * Rescind the offer by initiating a device removal 314 + */ 315 + static void vmbus_process_rescind_offer(struct work_struct *work) 316 + { 317 + struct vmbus_channel *channel = container_of(work, 318 + struct vmbus_channel, 319 + work); 320 + 321 + vmbus_child_device_unregister(channel->device_obj); 322 + } 313 323 314 324 /* 315 325 * vmbus_process_offer - Process the offer by creating a channel/device 316 326 * associated with this offer 317 327 */ 318 - static void vmbus_process_offer(void *context) 328 + static void vmbus_process_offer(struct work_struct *work) 319 329 { 320 - struct vmbus_channel *newchannel = context; 330 + struct vmbus_channel *newchannel = container_of(work, 331 + struct vmbus_channel, 332 + work); 321 333 struct vmbus_channel *channel; 322 334 bool fnew = true; 323 335 int ret; 324 336 int cnt; 325 337 unsigned long flags; 338 + 339 + /* The next possible work is rescind handling */ 340 + INIT_WORK(&newchannel->work, vmbus_process_rescind_offer); 326 341 327 342 /* Make sure this is a new offer */ 328 343 spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); ··· 425 406 } 426 407 427 408 /* 428 - * vmbus_process_rescind_offer - 429 - * Rescind the offer by initiating a device removal 430 - */ 431 - static void vmbus_process_rescind_offer(void *context) 432 - { 433 - struct vmbus_channel *channel = context; 434 - 435 - vmbus_child_device_unregister(channel->device_obj); 436 - } 437 - 438 - /* 439 409 * vmbus_onoffer - Handler for channel offers from vmbus in parent partition. 440 410 * 441 411 * We ignore all offers except network and storage offers. For each network and ··· 498 490 newchannel->monitor_bit = (u8)offer->monitorid % 32; 499 491 500 492 /* TODO: Make sure the offer comes from our parent partition */ 501 - osd_schedule_callback(newchannel->controlwq, vmbus_process_offer, 502 - newchannel); 493 + INIT_WORK(&newchannel->work, vmbus_process_offer); 494 + queue_work(newchannel->controlwq, &newchannel->work); 503 495 } 504 496 505 497 /* ··· 520 512 return; 521 513 } 522 514 523 - osd_schedule_callback(channel->controlwq, 524 - vmbus_process_rescind_offer, 525 - channel); 515 + /* work is initialized for vmbus_process_rescind_offer() from 516 + * vmbus_process_offer() where the channel got created */ 517 + queue_work(channel->controlwq, &channel->work); 526 518 } 527 519 528 520 /*
+1
drivers/staging/hv/channel_mgmt.h
··· 231 231 struct hv_device *device_obj; 232 232 233 233 struct timer_list poll_timer; /* SA-111 workaround */ 234 + struct work_struct work; 234 235 235 236 enum vmbus_channel_state state; 236 237