Lines Matching +full:extended +full:- +full:wait
1 // SPDX-License-Identifier: GPL-2.0+
38 * "s390cmf" -- enable cmf and allocate 2 MB of ram so measuring can be
40 * "s390cmf=<num>" -- enable cmf and allocate enough memory to measure
48 avg_utilization = -1,
49 /* basic and extended format: */
57 /* extended format only: */
63 * enum cmb_format - types of supported measurement block formats
69 * @CMF_AUTODETECT: default: use extended format when running on a machine
70 * supporting extended format, otherwise fall back to
76 CMF_AUTODETECT = -1,
80 * format - actual format for all measurement blocks
83 * or 1, indicating basic or extended format as described for
90 * struct cmb_operations - functions to use depending on cmb_format
180 struct subchannel *sch = to_subchannel(cdev->dev.parent); in set_schib()
183 sch->config.mme = mme; in set_schib()
184 sch->config.mbfc = mbfc; in set_schib()
187 sch->config.mba = address; in set_schib()
189 sch->config.mbi = address; in set_schib()
192 if (!mme && ret == -ENODEV) { in set_schib()
206 wait_queue_head_t wait; member
217 int ret = -ENODEV; in set_schib_wait()
219 spin_lock_irq(cdev->ccwlock); in set_schib_wait()
220 if (!cdev->private->cmb) in set_schib_wait()
224 if (ret != -EBUSY) in set_schib_wait()
228 if (cdev->private->state != DEV_STATE_ONLINE) in set_schib_wait()
231 init_waitqueue_head(&set_data.wait); in set_schib_wait()
237 cdev->private->state = DEV_STATE_CMFCHANGE; in set_schib_wait()
238 cdev->private->cmb_wait = &set_data; in set_schib_wait()
239 spin_unlock_irq(cdev->ccwlock); in set_schib_wait()
241 ret = wait_event_interruptible_timeout(set_data.wait, in set_schib_wait()
244 spin_lock_irq(cdev->ccwlock); in set_schib_wait()
247 set_data.ret = (ret == 0) ? -ETIME : ret; in set_schib_wait()
248 if (cdev->private->state == DEV_STATE_CMFCHANGE) in set_schib_wait()
249 cdev->private->state = DEV_STATE_ONLINE; in set_schib_wait()
252 cdev->private->cmb_wait = NULL; in set_schib_wait()
255 spin_unlock_irq(cdev->ccwlock); in set_schib_wait()
261 struct set_schib_struct *set_data = cdev->private->cmb_wait; in retry_set_schib()
266 set_data->ret = set_schib(cdev, set_data->mme, set_data->mbfc, in retry_set_schib()
267 set_data->address); in retry_set_schib()
268 wake_up(&set_data->wait); in retry_set_schib()
273 struct subchannel *sch = to_subchannel(cdev->dev.parent); in cmf_copy_block()
278 return -ENODEV; in cmf_copy_block()
280 if (scsw_fctl(&sch->schib.scsw) & SCSW_FCTL_START_FUNC) { in cmf_copy_block()
282 if ((!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_SUSPENDED)) && in cmf_copy_block()
283 (scsw_actl(&sch->schib.scsw) & in cmf_copy_block()
285 (!(scsw_stctl(&sch->schib.scsw) & SCSW_STCTL_SEC_STATUS))) in cmf_copy_block()
286 return -EBUSY; in cmf_copy_block()
288 cmb_data = cdev->private->cmb; in cmf_copy_block()
289 hw_block = cmb_data->hw_block; in cmf_copy_block()
290 memcpy(cmb_data->last_block, hw_block, cmb_data->size); in cmf_copy_block()
291 cmb_data->last_update = get_tod_clock(); in cmf_copy_block()
296 wait_queue_head_t wait; member
303 int ret = -ENODEV; in cmf_cmb_copy_wait()
305 spin_lock_irq(cdev->ccwlock); in cmf_cmb_copy_wait()
306 if (!cdev->private->cmb) in cmf_cmb_copy_wait()
310 if (ret != -EBUSY) in cmf_cmb_copy_wait()
313 if (cdev->private->state != DEV_STATE_ONLINE) in cmf_cmb_copy_wait()
316 init_waitqueue_head(©_block.wait); in cmf_cmb_copy_wait()
319 cdev->private->state = DEV_STATE_CMFUPDATE; in cmf_cmb_copy_wait()
320 cdev->private->cmb_wait = ©_block; in cmf_cmb_copy_wait()
321 spin_unlock_irq(cdev->ccwlock); in cmf_cmb_copy_wait()
323 ret = wait_event_interruptible(copy_block.wait, in cmf_cmb_copy_wait()
325 spin_lock_irq(cdev->ccwlock); in cmf_cmb_copy_wait()
328 copy_block.ret = -ERESTARTSYS; in cmf_cmb_copy_wait()
329 if (cdev->private->state == DEV_STATE_CMFUPDATE) in cmf_cmb_copy_wait()
330 cdev->private->state = DEV_STATE_ONLINE; in cmf_cmb_copy_wait()
333 cdev->private->cmb_wait = NULL; in cmf_cmb_copy_wait()
336 spin_unlock_irq(cdev->ccwlock); in cmf_cmb_copy_wait()
342 struct copy_block_struct *copy_block = cdev->private->cmb_wait; in cmf_retry_copy_block()
347 copy_block->ret = cmf_copy_block(cdev); in cmf_retry_copy_block()
348 wake_up(©_block->wait); in cmf_retry_copy_block()
355 spin_lock_irq(cdev->ccwlock); in cmf_generic_reset()
356 cmb_data = cdev->private->cmb; in cmf_generic_reset()
358 memset(cmb_data->last_block, 0, cmb_data->size); in cmf_generic_reset()
363 memset(cmb_data->hw_block, 0, cmb_data->size); in cmf_generic_reset()
364 cmb_data->last_update = 0; in cmf_generic_reset()
366 cdev->private->cmb_start_time = get_tod_clock(); in cmf_generic_reset()
367 spin_unlock_irq(cdev->ccwlock); in cmf_generic_reset()
371 * struct cmb_area - container for global cmb data
406 * struct cmb - basic channel measurement block
445 spin_lock_irq(cdev->ccwlock); in alloc_cmb_single()
446 if (!list_empty(&cdev->private->cmb_list)) { in alloc_cmb_single()
447 ret = -EBUSY; in alloc_cmb_single()
454 * remains sorted by ->cmb->hw_data pointers. in alloc_cmb_single()
459 data = node->cmb; in alloc_cmb_single()
460 if ((struct cmb*)data->hw_block > cmb) in alloc_cmb_single()
464 if (cmb - cmb_area.mem >= cmb_area.num_channels) { in alloc_cmb_single()
465 ret = -ENOMEM; in alloc_cmb_single()
470 list_add_tail(&cdev->private->cmb_list, &node->cmb_list); in alloc_cmb_single()
471 cmb_data->hw_block = cmb; in alloc_cmb_single()
472 cdev->private->cmb = cmb_data; in alloc_cmb_single()
475 spin_unlock_irq(cdev->ccwlock); in alloc_cmb_single()
489 return -ENOMEM; in alloc_cmb()
491 cmb_data->last_block = kzalloc(sizeof(struct cmb), GFP_KERNEL); in alloc_cmb()
492 if (!cmb_data->last_block) { in alloc_cmb()
494 return -ENOMEM; in alloc_cmb()
496 cmb_data->size = sizeof(struct cmb); in alloc_cmb()
513 ret = -ENOMEM; in alloc_cmb()
528 kfree(cmb_data->last_block); in alloc_cmb()
540 spin_lock_irq(cdev->ccwlock); in free_cmb()
542 priv = cdev->private; in free_cmb()
543 cmb_data = priv->cmb; in free_cmb()
544 priv->cmb = NULL; in free_cmb()
546 kfree(cmb_data->last_block); in free_cmb()
548 list_del_init(&priv->cmb_list); in free_cmb()
557 spin_unlock_irq(cdev->ccwlock); in free_cmb()
567 spin_lock_irqsave(cdev->ccwlock, flags); in set_cmb()
568 if (!cdev->private->cmb) { in set_cmb()
569 spin_unlock_irqrestore(cdev->ccwlock, flags); in set_cmb()
570 return -EINVAL; in set_cmb()
572 cmb_data = cdev->private->cmb; in set_cmb()
573 offset = mme ? (struct cmb *)cmb_data->hw_block - cmb_area.mem : 0; in set_cmb()
574 spin_unlock_irqrestore(cdev->ccwlock, flags); in set_cmb()
589 elapsed_time = get_tod_clock() - start_time; in __cmb_utilization()
604 spin_lock_irqsave(cdev->ccwlock, flags); in read_cmb()
605 cmb_data = cdev->private->cmb; in read_cmb()
609 cmb = cmb_data->hw_block; in read_cmb()
612 ret = __cmb_utilization(cmb->device_connect_time, in read_cmb()
613 cmb->function_pending_time, in read_cmb()
614 cmb->device_disconnect_time, in read_cmb()
615 cdev->private->cmb_start_time); in read_cmb()
618 ret = cmb->ssch_rsch_count; in read_cmb()
621 ret = cmb->sample_count; in read_cmb()
624 val = cmb->device_connect_time; in read_cmb()
627 val = cmb->function_pending_time; in read_cmb()
630 val = cmb->device_disconnect_time; in read_cmb()
633 val = cmb->control_unit_queuing_time; in read_cmb()
636 val = cmb->device_active_only_time; in read_cmb()
641 ret = time_to_avg_nsec(val, cmb->sample_count); in read_cmb()
643 spin_unlock_irqrestore(cdev->ccwlock, flags); in read_cmb()
658 spin_lock_irqsave(cdev->ccwlock, flags); in readall_cmb()
659 cmb_data = cdev->private->cmb; in readall_cmb()
661 ret = -ENODEV; in readall_cmb()
664 if (cmb_data->last_update == 0) { in readall_cmb()
665 ret = -EAGAIN; in readall_cmb()
668 cmb = cmb_data->last_block; in readall_cmb()
669 time = cmb_data->last_update - cdev->private->cmb_start_time; in readall_cmb()
674 data->size = offsetof(struct cmbdata, device_busy_time); in readall_cmb()
676 data->elapsed_time = tod_to_ns(time); in readall_cmb()
679 data->ssch_rsch_count = cmb->ssch_rsch_count; in readall_cmb()
680 data->sample_count = cmb->sample_count; in readall_cmb()
683 data->device_connect_time = time_to_nsec(cmb->device_connect_time); in readall_cmb()
684 data->function_pending_time = time_to_nsec(cmb->function_pending_time); in readall_cmb()
685 data->device_disconnect_time = in readall_cmb()
686 time_to_nsec(cmb->device_disconnect_time); in readall_cmb()
687 data->control_unit_queuing_time in readall_cmb()
688 = time_to_nsec(cmb->control_unit_queuing_time); in readall_cmb()
689 data->device_active_only_time in readall_cmb()
690 = time_to_nsec(cmb->device_active_only_time); in readall_cmb()
693 spin_unlock_irqrestore(cdev->ccwlock, flags); in readall_cmb()
706 spin_lock_irq(cdev->ccwlock); in cmf_enabled()
707 enabled = !!cdev->private->cmb; in cmf_enabled()
708 spin_unlock_irq(cdev->ccwlock); in cmf_enabled()
725 /* ******** extended cmb handling ********/
728 * struct cmbe - extended channel measurement block
764 int ret = -ENOMEM; in alloc_cmbe()
774 cmb_data->last_block = kzalloc(sizeof(struct cmbe), GFP_KERNEL); in alloc_cmbe()
775 if (!cmb_data->last_block) in alloc_cmbe()
778 cmb_data->size = sizeof(*cmbe); in alloc_cmbe()
779 cmb_data->hw_block = cmbe; in alloc_cmbe()
782 spin_lock_irq(cdev->ccwlock); in alloc_cmbe()
783 if (cdev->private->cmb) in alloc_cmbe()
786 cdev->private->cmb = cmb_data; in alloc_cmbe()
791 list_add_tail(&cdev->private->cmb_list, &cmb_area.list); in alloc_cmbe()
793 spin_unlock_irq(cdev->ccwlock); in alloc_cmbe()
798 spin_unlock_irq(cdev->ccwlock); in alloc_cmbe()
800 ret = -EBUSY; in alloc_cmbe()
803 kfree(cmb_data->last_block); in alloc_cmbe()
815 spin_lock_irq(cdev->ccwlock); in free_cmbe()
816 cmb_data = cdev->private->cmb; in free_cmbe()
817 cdev->private->cmb = NULL; in free_cmbe()
819 kfree(cmb_data->last_block); in free_cmbe()
820 kmem_cache_free(cmbe_cache, cmb_data->hw_block); in free_cmbe()
825 list_del_init(&cdev->private->cmb_list); in free_cmbe()
828 spin_unlock_irq(cdev->ccwlock); in free_cmbe()
838 spin_lock_irqsave(cdev->ccwlock, flags); in set_cmbe()
839 if (!cdev->private->cmb) { in set_cmbe()
840 spin_unlock_irqrestore(cdev->ccwlock, flags); in set_cmbe()
841 return -EINVAL; in set_cmbe()
843 cmb_data = cdev->private->cmb; in set_cmbe()
844 mba = mme ? (unsigned long) cmb_data->hw_block : 0; in set_cmbe()
845 spin_unlock_irqrestore(cdev->ccwlock, flags); in set_cmbe()
858 spin_lock_irqsave(cdev->ccwlock, flags); in read_cmbe()
859 cmb_data = cdev->private->cmb; in read_cmbe()
863 cmb = cmb_data->hw_block; in read_cmbe()
866 ret = __cmb_utilization(cmb->device_connect_time, in read_cmbe()
867 cmb->function_pending_time, in read_cmbe()
868 cmb->device_disconnect_time, in read_cmbe()
869 cdev->private->cmb_start_time); in read_cmbe()
872 ret = cmb->ssch_rsch_count; in read_cmbe()
875 ret = cmb->sample_count; in read_cmbe()
878 val = cmb->device_connect_time; in read_cmbe()
881 val = cmb->function_pending_time; in read_cmbe()
884 val = cmb->device_disconnect_time; in read_cmbe()
887 val = cmb->control_unit_queuing_time; in read_cmbe()
890 val = cmb->device_active_only_time; in read_cmbe()
893 val = cmb->device_busy_time; in read_cmbe()
896 val = cmb->initial_command_response_time; in read_cmbe()
901 ret = time_to_avg_nsec(val, cmb->sample_count); in read_cmbe()
903 spin_unlock_irqrestore(cdev->ccwlock, flags); in read_cmbe()
918 spin_lock_irqsave(cdev->ccwlock, flags); in readall_cmbe()
919 cmb_data = cdev->private->cmb; in readall_cmbe()
921 ret = -ENODEV; in readall_cmbe()
924 if (cmb_data->last_update == 0) { in readall_cmbe()
925 ret = -EAGAIN; in readall_cmbe()
928 time = cmb_data->last_update - cdev->private->cmb_start_time; in readall_cmbe()
933 data->size = offsetof(struct cmbdata, device_busy_time); in readall_cmbe()
935 data->elapsed_time = tod_to_ns(time); in readall_cmbe()
937 cmb = cmb_data->last_block; in readall_cmbe()
939 data->ssch_rsch_count = cmb->ssch_rsch_count; in readall_cmbe()
940 data->sample_count = cmb->sample_count; in readall_cmbe()
943 data->device_connect_time = time_to_nsec(cmb->device_connect_time); in readall_cmbe()
944 data->function_pending_time = time_to_nsec(cmb->function_pending_time); in readall_cmbe()
945 data->device_disconnect_time = in readall_cmbe()
946 time_to_nsec(cmb->device_disconnect_time); in readall_cmbe()
947 data->control_unit_queuing_time in readall_cmbe()
948 = time_to_nsec(cmb->control_unit_queuing_time); in readall_cmbe()
949 data->device_active_only_time in readall_cmbe()
950 = time_to_nsec(cmb->device_active_only_time); in readall_cmbe()
951 data->device_busy_time = time_to_nsec(cmb->device_busy_time); in readall_cmbe()
952 data->initial_command_response_time in readall_cmbe()
953 = time_to_nsec(cmb->initial_command_response_time); in readall_cmbe()
957 spin_unlock_irqrestore(cdev->ccwlock, flags); in readall_cmbe()
992 spin_lock_irq(cdev->ccwlock); in cmb_show_avg_sample_interval()
994 interval = get_tod_clock() - cdev->private->cmb_start_time; in cmb_show_avg_sample_interval()
998 interval = -1; in cmb_show_avg_sample_interval()
999 spin_unlock_irq(cdev->ccwlock); in cmb_show_avg_sample_interval()
1105 ret = -EINVAL; in cmb_enable_store()
1113 * enable_cmf() - switch on the channel measurement for a specific device
1121 * non-atomic
1127 device_lock(&cdev->dev); in enable_cmf()
1129 cmbops->reset(cdev); in enable_cmf()
1132 get_device(&cdev->dev); in enable_cmf()
1133 ret = cmbops->alloc(cdev); in enable_cmf()
1136 cmbops->reset(cdev); in enable_cmf()
1137 ret = sysfs_create_group(&cdev->dev.kobj, cmbops->attr_group); in enable_cmf()
1139 cmbops->free(cdev); in enable_cmf()
1142 ret = cmbops->set(cdev, 2); in enable_cmf()
1144 sysfs_remove_group(&cdev->dev.kobj, cmbops->attr_group); in enable_cmf()
1145 cmbops->free(cdev); in enable_cmf()
1149 put_device(&cdev->dev); in enable_cmf()
1151 device_unlock(&cdev->dev); in enable_cmf()
1156 * __disable_cmf() - switch off the channel measurement for a specific device
1162 * non-atomic, device_lock() held.
1168 ret = cmbops->set(cdev, 0); in __disable_cmf()
1172 sysfs_remove_group(&cdev->dev.kobj, cmbops->attr_group); in __disable_cmf()
1173 cmbops->free(cdev); in __disable_cmf()
1174 put_device(&cdev->dev); in __disable_cmf()
1180 * disable_cmf() - switch off the channel measurement for a specific device
1186 * non-atomic
1192 device_lock(&cdev->dev); in disable_cmf()
1194 device_unlock(&cdev->dev); in disable_cmf()
1200 * cmf_read() - read one value from the current channel measurement block
1211 return cmbops->read(cdev, index); in cmf_read()
1215 * cmf_readall() - read the current channel measurement block
1226 return cmbops->readall(cdev, data); in cmf_readall()
1229 /* Re-enable cmf when a disconnected device becomes available again. */
1232 cmbops->reset(cdev); in cmf_reenable()
1233 return cmbops->set(cdev, 2); in cmf_reenable()
1237 * cmf_reactivate() - reactivate measurement block updates
1254 return cmbe_cache ? 0 : -ENOMEM; in init_cmbe()
1265 * machine supporting extended measurement blocks, otherwise fall back in init_cmf()
1285 format_string = "extended"; in init_cmf()
1293 return -EINVAL; in init_cmf()