History

coresight: Add default sink selection to CoreSight base

Adds a method to select a suitable sink connected to a given source. In cases where no sink is defined, the coresight_find_default_sink routine can search from a given source, through the child connections until a suitable sink is found. The suitability is defined in by the sink coresight_dev_subtype on the CoreSight device, and the distance from the source by counting connections. Higher value subtype is preferred - where these are equal, shorter distance from source is used as a tie-break. This allows for default sink to be discovered were none is specified (e.g. perf command line)

Mike Leach committed 6 years ago

Commit 0336bdf1 parent d021f5c3 files · +171 −0Browse files

Unified · Split

3 files
  1. drivers/hwtracing/coresight/coresight-priv.h +2 −0
  2. drivers/hwtracing/coresight/coresight.c +166 −0
  3. include/linux/coresight.h +3 −0
drivers/hwtracing/coresight/coresight-priv.h+2−0
@@ -150,6 +150,8 @@ int coresight_enable_path(struct list_head *path, u32 mode, void *sink_data); · 149 unmodified lines
150struct coresight_device *coresight_get_sink(struct list_head *path);150struct coresight_device *coresight_get_sink(struct list_head *path);
151struct coresight_device *coresight_get_enabled_sink(bool reset);151struct coresight_device *coresight_get_enabled_sink(bool reset);
152struct coresight_device *coresight_get_sink_by_id(u32 id);152struct coresight_device *coresight_get_sink_by_id(u32 id);
153struct coresight_device *
154coresight_find_default_sink(struct coresight_device *csdev);
153struct list_head *coresight_build_path(struct coresight_device *csdev,155struct list_head *coresight_build_path(struct coresight_device *csdev,
154 struct coresight_device *sink);156 struct coresight_device *sink);
155void coresight_release_path(struct list_head *path);157void coresight_release_path(struct list_head *path);
drivers/hwtracing/coresight/coresight.c+166−0
@@ -769,6 +769,171 @@ void coresight_release_path(struct list_head *path) · 768 unmodified lines
769 path = NULL;769 path = NULL;
770}770}
771 771
772/* return true if the device is a suitable type for a default sink */
773static inline bool coresight_is_def_sink_type(struct coresight_device *csdev)
774{
775 /* sink & correct subtype */
776 if (((csdev->type == CORESIGHT_DEV_TYPE_SINK) ||
777 (csdev->type == CORESIGHT_DEV_TYPE_LINKSINK)) &&
778 (csdev->subtype.sink_subtype >= CORESIGHT_DEV_SUBTYPE_SINK_BUFFER))
779 return true;
780 return false;
781}
782
783/**
784 * coresight_select_best_sink - return the best sink for use as default from
785 * the two provided.
786 *
787 * @sink: current best sink.
788 * @depth: search depth where current sink was found.
789 * @new_sink: new sink for comparison with current sink.
790 * @new_depth: search depth where new sink was found.
791 *
792 * Sinks prioritised according to coresight_dev_subtype_sink, with only
793 * subtypes CORESIGHT_DEV_SUBTYPE_SINK_BUFFER or higher being used.
794 *
795 * Where two sinks of equal priority are found, the sink closest to the
796 * source is used (smallest search depth).
797 *
798 * return @new_sink & update @depth if better than @sink, else return @sink.
799 */
800static struct coresight_device *
801coresight_select_best_sink(struct coresight_device *sink, int *depth,
802 struct coresight_device *new_sink, int new_depth)
803{
804 bool update = false;
805
806 if (!sink) {
807 /* first found at this level */
808 update = true;
809 } else if (new_sink->subtype.sink_subtype >
810 sink->subtype.sink_subtype) {
811 /* found better sink */
812 update = true;
813 } else if ((new_sink->subtype.sink_subtype ==
814 sink->subtype.sink_subtype) &&
815 (*depth > new_depth)) {
816 /* found same but closer sink */
817 update = true;
818 }
819
820 if (update)
821 *depth = new_depth;
822 return update ? new_sink : sink;
823}
824
825/**
826 * coresight_find_sink - recursive function to walk trace connections from
827 * source to find a suitable default sink.
828 *
829 * @csdev: source / current device to check.
830 * @depth: [in] search depth of calling dev, [out] depth of found sink.
831 *
832 * This will walk the connection path from a source (ETM) till a suitable
833 * sink is encountered and return that sink to the original caller.
834 *
835 * If current device is a plain sink return that & depth, otherwise recursively
836 * call child connections looking for a sink. Select best possible using
837 * coresight_select_best_sink.
838 *
839 * return best sink found, or NULL if not found at this node or child nodes.
840 */
841static struct coresight_device *
842coresight_find_sink(struct coresight_device *csdev, int *depth)
843{
844 int i, curr_depth = *depth + 1, found_depth = 0;
845 struct coresight_device *found_sink = NULL;
846
847 if (coresight_is_def_sink_type(csdev)) {
848 found_depth = curr_depth;
849 found_sink = csdev;
850 if (csdev->type == CORESIGHT_DEV_TYPE_SINK)
851 goto return_def_sink;
852 /* look past LINKSINK for something better */
853 }
854
855 /*
856 * Not a sink we want - or possible child sink may be better.
857 * recursively explore each port found on this element.
858 */
859 for (i = 0; i < csdev->pdata->nr_outport; i++) {
860 struct coresight_device *child_dev, *sink = NULL;
861 int child_depth = curr_depth;
862
863 child_dev = csdev->pdata->conns[i].child_dev;
864 if (child_dev)
865 sink = coresight_find_sink(child_dev, &child_depth);
866
867 if (sink)
868 found_sink = coresight_select_best_sink(found_sink,
869 &found_depth,
870 sink,
871 child_depth);
872 }
873
874return_def_sink:
875 /* return found sink and depth */
876 if (found_sink)
877 *depth = found_depth;
878 return found_sink;
879}
880
881/**
882 * coresight_find_default_sink: Find a sink suitable for use as a
883 * default sink.
884 *
885 * @csdev: starting source to find a connected sink.
886 *
887 * Walks connections graph looking for a suitable sink to enable for the
888 * supplied source. Uses CoreSight device subtypes and distance from source
889 * to select the best sink.
890 *
891 * If a sink is found, then the default sink for this device is set and
892 * will be automatically used in future.
893 *
894 * Used in cases where the CoreSight user (perf / sysfs) has not selected a
895 * sink.
896 */
897struct coresight_device *
898coresight_find_default_sink(struct coresight_device *csdev)
899{
900 int depth = 0;
901
902 /* look for a default sink if we have not found for this device */
903 if (!csdev->def_sink)
904 csdev->def_sink = coresight_find_sink(csdev, &depth);
905 return csdev->def_sink;
906}
907
908static int coresight_remove_sink_ref(struct device *dev, void *data)
909{
910 struct coresight_device *sink = data;
911 struct coresight_device *source = to_coresight_device(dev);
912
913 if (source->def_sink == sink)
914 source->def_sink = NULL;
915 return 0;
916}
917
918/**
919 * coresight_clear_default_sink: Remove all default sink references to the
920 * supplied sink.
921 *
922 * If supplied device is a sink, then check all the bus devices and clear
923 * out all the references to this sink from the coresight_device def_sink
924 * parameter.
925 *
926 * @csdev: coresight sink - remove references to this from all sources.
927 */
928static void coresight_clear_default_sink(struct coresight_device *csdev)
929{
930 if ((csdev->type == CORESIGHT_DEV_TYPE_SINK) ||
931 (csdev->type == CORESIGHT_DEV_TYPE_LINKSINK)) {
932 bus_for_each_dev(&coresight_bustype, NULL, csdev,
933 coresight_remove_sink_ref);
934 }
935}
936
772/** coresight_validate_source - make sure a source has the right credentials937/** coresight_validate_source - make sure a source has the right credentials
773 * @csdev: the device structure for a source.938 * @csdev: the device structure for a source.
774 * @function: the function this was called from.939 * @function: the function this was called from.
@@ -1358,6 +1523,7 @@ void coresight_unregister(struct coresight_device *csdev) · 583 unmodified lines
1358 etm_perf_del_symlink_sink(csdev);1523 etm_perf_del_symlink_sink(csdev);
1359 /* Remove references of that device in the topology */1524 /* Remove references of that device in the topology */
1360 coresight_remove_conns(csdev);1525 coresight_remove_conns(csdev);
1526 coresight_clear_default_sink(csdev);
1361 coresight_release_platform_data(csdev, csdev->pdata);1527 coresight_release_platform_data(csdev, csdev->pdata);
1362 device_unregister(&csdev->dev);1528 device_unregister(&csdev->dev);
1363}1529}
include/linux/coresight.h+3−0
@@ -48,6 +48,7 @@ enum coresight_dev_subtype_sink { · 47 unmodified lines
48 CORESIGHT_DEV_SUBTYPE_SINK_NONE,48 CORESIGHT_DEV_SUBTYPE_SINK_NONE,
49 CORESIGHT_DEV_SUBTYPE_SINK_PORT,49 CORESIGHT_DEV_SUBTYPE_SINK_PORT,
50 CORESIGHT_DEV_SUBTYPE_SINK_BUFFER,50 CORESIGHT_DEV_SUBTYPE_SINK_BUFFER,
51 CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM,
51};52};
52 53
53enum coresight_dev_subtype_link {54enum coresight_dev_subtype_link {
@@ -182,6 +183,7 @@ struct coresight_sysfs_link { · 128 unmodified lines
182 * happens when a source has been selected and a path is enabled183 * happens when a source has been selected and a path is enabled
183 * from source to that sink.184 * from source to that sink.
184 * @ea: Device attribute for sink representation under PMU directory.185 * @ea: Device attribute for sink representation under PMU directory.
186 * @def_sink: cached reference to default sink found for this device.
185 * @ect_dev: Associated cross trigger device. Not part of the trace data187 * @ect_dev: Associated cross trigger device. Not part of the trace data
186 * path or connections.188 * path or connections.
187 * @nr_links: number of sysfs links created to other components from this189 * @nr_links: number of sysfs links created to other components from this
@@ -200,6 +202,7 @@ struct coresight_device { · 12 unmodified lines
200 /* sink specific fields */202 /* sink specific fields */
201 bool activated; /* true only if a sink is part of a path */203 bool activated; /* true only if a sink is part of a path */
202 struct dev_ext_attribute *ea;204 struct dev_ext_attribute *ea;
205 struct coresight_device *def_sink;
203 /* cross trigger handling */206 /* cross trigger handling */
204 struct coresight_device *ect_dev;207 struct coresight_device *ect_dev;
205 /* sysfs links between components */208 /* sysfs links between components */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t