[Intel-gfx] [RFC v2] GuC firmware versioning change
See https://lists.freedesktop.org/archives/intel-gfx/2018-October/178452.html for RFC v1 and the helpful feedback incorporated into this v2. The GuC firmware team is proposing a change to the firmware versioning scheme. The goal is to more accurately track the firmware interface to help users manage dependencies on that interface. The proposed scheme is based on semver.org. The proposed version number would consist of these 3 mandatory fields in order of significance: MAJOR.MINOR.PATCH. Contrast this with the 2 fields in the current version number: MAJOR.MINOR. The version block in the firmware header will be refactored to contain these 3 fields so that i915 can continue to verify the version before loading. The firmware file would adopt a change of naming format to match: Current: _guc_ver_.bin (skl_guc_ver9_33.bin) Proposed: _guc_ver__.bin (skl_guc_ver5_4_7.bin) The MAJOR number conforms to the major in semver.org. It increments on a backwards incompatible change of the interface. The MAJOR number basically works the same between the current and proposed versioning schemes. The MINOR number conforms to the minor in semver.org. It increments on a backwards compatible change of the interface (new interfaces that are optional to use). It will also increment on substantial new internal functionality that doesn't affect the interface but should be called out to the user. It resets to 0 on a change of MAJOR. The MINOR number in the current versioning scheme increments on any backwards compatible change. The proposed versioning scheme breaks this into the MINOR number just described and the PATCH number below. The PATCH number conforms to the patch in semver.org. It increments on a backwards compatible internal change, usually a bug fix. It resets to 0 on a change of MINOR. The MAJOR.MINOR collectively define the interface version. Because the MINOR may also increment on a substantial internal change, it doesn't always mark an interface change, e.g. 4.5 and 4.6 may have identical interfaces. But the determination of interface compatibility is unchanged, e.g. 4.6 is always backwards compatible with 4.5. Each MAJOR.MINOR may continue to receive internal fixes along a branch even after the main branch has moved on to another MAJOR.MINOR. Releases from these fix-only branches increment only the PATCH number on that MAJOR.MINOR, and therefore remain semantically consistent with the main branch. Consider an example: v1.0.0 v1.0.1 v1.0.2 v1.1.0 v1.1.1 O--O--O--O--O<-- main adopts v1.1.x \ \ \ O--O <-- fixes for interface v1.0.x v1.0.3 v1.0.4 The key here is that the branching happened from the last fix (v1.0.2) on the main branch prior to the change of interface (v1.1.0). As long as only fixes are applied to v1.0.x, there is no risk of version number clash. All of these release versions remain semantically connected with one small caveat. If this set of release versions came sequentially along a single branch, one could infer that the exact fixes in v1.0.4 were inherited by v1.1.0. With this "hidden" branching, this may not be true as this example shows. One should always review the release notes to confirm release ancestry and content. The above scenario of continued fixes on a given interface version represents the most common form of release branching expected, and can be handled quite smoothly within the proposed scheme as shown. But it may also be necessary to branch from an arbitrary point and with an arbitrary scope of changes. Such a scenario could not be handled with the basic 3 fields without violating semver.org semantics. One or more additional version fields will need to be defined. The GuC firmware team intends to avoid this scenario as long as possible, though some day a customer or other situation might force it upon us. For now we will just defer the design for handling the aforementioned scenario, though I am summarizing some options below to be considered if and when. None of these are being put into effect immediately as part of the proposed change. At minimum we will need a 4th field to contain a branch ID. This will be a numeric ID in the firmware image header, but can be mapped to a descriptive branch string via a table that is part of the official firmware interface documentation. If and when the branch ID field is added, it will start with a value of 1 for that first branch, the mainline being implicitly branch ID 0. There seems to be two logical choices for how to version the releases coming from a branch. The best choice depends on the intent of the branch as described below. For branches that are short-lived, primarily for fixes, and make only minor or no changes to the interface, the ability to track their relationship to the mainline is of utmost importanc
Re: [Intel-gfx] [RFC] GuC firmware versioning change
On Thu, Oct 18, 2018 at 11:12:21AM -0700, Rodrigo Vivi wrote: > On Thu, Oct 18, 2018 at 10:32:37AM -0700, Jeff McGee wrote: > > On Thu, Oct 18, 2018 at 11:57:06AM +0200, Daniel Vetter wrote: > > > On Fri, Oct 12, 2018 at 11:45 PM Jeff McGee wrote: > > > > > > > > On Fri, Oct 12, 2018 at 02:33:26PM -0700, Jeff McGee wrote: > > > > > On Fri, Oct 12, 2018 at 01:51:46PM -0700, Rodrigo Vivi wrote: > > > > > > On Fri, Oct 12, 2018 at 01:24:30PM -0700, Jeff McGee wrote: > > > > > > > The GuC firmware team is proposing a change to the firmware > > > > > > > versioning scheme. > > > > > > > The goal is to more accurately track the firmware interface to > > > > > > > help users > > > > > > > manage dependencies on that interface. The proposed scheme is > > > > > > > based on > > > > > > > semver.org with some additions to handle branching. > > > > > > > > > > > > > > The proposed version number would have 4 fields: > > > > > > > BASE.MAJOR.MINOR.PATCH. > > > > > > > Contrast this with the 2 fields in the current version number: > > > > > > > MAJOR.MINOR. > > > > > > > Side note, the current firmware encodes a BRANCH and CLIENT > > > > > > > number as well, but > > > > > > > they have not been needed by i915. So a firmware released with > > > > > > > the proposed > > > > > > > scheme would be named > > > > > > > _guc_ver___.bin > > > > > > > (ex: skl_guc_ver1_5_4_7.bin) instead of the current > > > > > > > _guc_ver_.bin (ex: skl_guc_ver9_33.bin). > > > > > > > > > > > > > > The BASE number is an ID that is used to identify a set of > > > > > > > releases in which > > > > > > > the MAJOR.MINOR.PATCH semantics are consistent. In other words, > > > > > > > two releases > > > > > > > from the same BASE can be compared via their MAJOR.MINOR.PATCH to > > > > > > > infer their > > > > > > > relationship as described below. Two releases from a different > > > > > > > BASE cannot be > > > > > > > reliably compared. The BASE number facilitates arbitrary > > > > > > > branching which can > > > > > > > create duplicate and/or disconnected MAJOR.MINOR.PATCH versions. > > > > > > > This type of > > > > > > > branching is expected to be rare, and so BASE will rarely change. > > > > > > > When a new > > > > > > > BASE is created, the MAJOR.MINOR.PATCH reset to starting values. > > > > > > > > > > > > Could you please clarify a bit what BASE means? > > > > > > What would be a different BASE? > > > > > > > > > > > > > > > > The BASE number supports general branching that would cause version > > > > > number > > > > > conflicts. Branching for firmware releases is not desirable, but it > > > > > is a > > > > > practical reality. Therefore the versioning scheme must accomodate > > > > > it. Let's > > > > > say that a high-priority request is made to put specific updates on > > > > > an old > > > > > release that said customer is locked on. Those updates could include > > > > > any sort > > > > > of change including interface change. Then we have a sequence like > > > > > below: > > > > > > > > > > v1.1.0.0 v1.1.0.1 v1.1.0.2 v1.1.0.3 v1.1.1.0 > > > > > O--O--O--O--O > > > > >\ > > > > > \ > > > > > \ > > > > > O--O > > > > > v2.1.1.0 v2.1.1.1 > > > > > > > > > > You can see that if we don't have a BASE number that changes from 1 > > > > > to 2, then > > > > > we end up with duplicated v1.1.0 along the different branches which > > > > > are not the > > > > > same. As I wrote, this should be a very rare scenario, but it can >
Re: [Intel-gfx] [RFC] GuC firmware versioning change
On Thu, Oct 18, 2018 at 11:57:06AM +0200, Daniel Vetter wrote: > On Fri, Oct 12, 2018 at 11:45 PM Jeff McGee wrote: > > > > On Fri, Oct 12, 2018 at 02:33:26PM -0700, Jeff McGee wrote: > > > On Fri, Oct 12, 2018 at 01:51:46PM -0700, Rodrigo Vivi wrote: > > > > On Fri, Oct 12, 2018 at 01:24:30PM -0700, Jeff McGee wrote: > > > > > The GuC firmware team is proposing a change to the firmware > > > > > versioning scheme. > > > > > The goal is to more accurately track the firmware interface to help > > > > > users > > > > > manage dependencies on that interface. The proposed scheme is based on > > > > > semver.org with some additions to handle branching. > > > > > > > > > > The proposed version number would have 4 fields: > > > > > BASE.MAJOR.MINOR.PATCH. > > > > > Contrast this with the 2 fields in the current version number: > > > > > MAJOR.MINOR. > > > > > Side note, the current firmware encodes a BRANCH and CLIENT number as > > > > > well, but > > > > > they have not been needed by i915. So a firmware released with the > > > > > proposed > > > > > scheme would be named > > > > > _guc_ver___.bin > > > > > (ex: skl_guc_ver1_5_4_7.bin) instead of the current > > > > > _guc_ver_.bin (ex: skl_guc_ver9_33.bin). > > > > > > > > > > The BASE number is an ID that is used to identify a set of releases > > > > > in which > > > > > the MAJOR.MINOR.PATCH semantics are consistent. In other words, two > > > > > releases > > > > > from the same BASE can be compared via their MAJOR.MINOR.PATCH to > > > > > infer their > > > > > relationship as described below. Two releases from a different BASE > > > > > cannot be > > > > > reliably compared. The BASE number facilitates arbitrary branching > > > > > which can > > > > > create duplicate and/or disconnected MAJOR.MINOR.PATCH versions. This > > > > > type of > > > > > branching is expected to be rare, and so BASE will rarely change. > > > > > When a new > > > > > BASE is created, the MAJOR.MINOR.PATCH reset to starting values. > > > > > > > > Could you please clarify a bit what BASE means? > > > > What would be a different BASE? > > > > > > > > > > The BASE number supports general branching that would cause version number > > > conflicts. Branching for firmware releases is not desirable, but it is a > > > practical reality. Therefore the versioning scheme must accomodate it. > > > Let's > > > say that a high-priority request is made to put specific updates on an old > > > release that said customer is locked on. Those updates could include any > > > sort > > > of change including interface change. Then we have a sequence like below: > > > > > > v1.1.0.0 v1.1.0.1 v1.1.0.2 v1.1.0.3 v1.1.1.0 > > > O--O--O--O--O > > >\ > > > \ > > > \ > > > O--O > > > v2.1.1.0 v2.1.1.1 > > > > > > You can see that if we don't have a BASE number that changes from 1 to 2, > > > then > > > we end up with duplicated v1.1.0 along the different branches which are > > > not the > > > same. As I wrote, this should be a very rare scenario, but it can happen. > > > Maybe > > > upstream will always be supplied with releases from the "main" BASE, and > > > you > > > can ignore this field, but it needs to be there for other firmware > > > distributions. > > The way this is usually solved in semver is to not prepend a BASE, but > postfix a branch-specific version, while keeping the mainline version > unchanged. So > > v2.1.1.0 becomes v1.1.0.1-branch1-0 > v2.1.1.1 becomes v1.1.0.1-branch1-1 > > With the rule that branches are explicitly unsorted (that's denoted by > the - - around them, instead o using dots), so not comparable. Bonus > points if you name the branch points by the customers (could be the > product, or internal customer group or whatever) to make these names > slightly more meaningful. > I don't see any mention of branch handling on semver.org. It discusses using h
Re: [Intel-gfx] [RFC] GuC firmware versioning change
On Fri, Oct 12, 2018 at 02:33:26PM -0700, Jeff McGee wrote: > On Fri, Oct 12, 2018 at 01:51:46PM -0700, Rodrigo Vivi wrote: > > On Fri, Oct 12, 2018 at 01:24:30PM -0700, Jeff McGee wrote: > > > The GuC firmware team is proposing a change to the firmware versioning > > > scheme. > > > The goal is to more accurately track the firmware interface to help users > > > manage dependencies on that interface. The proposed scheme is based on > > > semver.org with some additions to handle branching. > > > > > > The proposed version number would have 4 fields: BASE.MAJOR.MINOR.PATCH. > > > Contrast this with the 2 fields in the current version number: > > > MAJOR.MINOR. > > > Side note, the current firmware encodes a BRANCH and CLIENT number as > > > well, but > > > they have not been needed by i915. So a firmware released with the > > > proposed > > > scheme would be named _guc_ver___.bin > > > (ex: skl_guc_ver1_5_4_7.bin) instead of the current > > > _guc_ver_.bin (ex: skl_guc_ver9_33.bin). > > > > > > The BASE number is an ID that is used to identify a set of releases in > > > which > > > the MAJOR.MINOR.PATCH semantics are consistent. In other words, two > > > releases > > > from the same BASE can be compared via their MAJOR.MINOR.PATCH to infer > > > their > > > relationship as described below. Two releases from a different BASE > > > cannot be > > > reliably compared. The BASE number facilitates arbitrary branching which > > > can > > > create duplicate and/or disconnected MAJOR.MINOR.PATCH versions. This > > > type of > > > branching is expected to be rare, and so BASE will rarely change. When a > > > new > > > BASE is created, the MAJOR.MINOR.PATCH reset to starting values. > > > > Could you please clarify a bit what BASE means? > > What would be a different BASE? > > > > The BASE number supports general branching that would cause version number > conflicts. Branching for firmware releases is not desirable, but it is a > practical reality. Therefore the versioning scheme must accomodate it. Let's > say that a high-priority request is made to put specific updates on an old > release that said customer is locked on. Those updates could include any sort > of change including interface change. Then we have a sequence like below: > > v1.1.0.0 v1.1.0.1 v1.1.0.2 v1.1.0.3 v1.1.1.0 > O--O--O--O--O >\ > \ > \ > O--O > v2.1.1.0 v2.1.1.1 > > You can see that if we don't have a BASE number that changes from 1 to 2, then > we end up with duplicated v1.1.0 along the different branches which are not > the > same. As I wrote, this should be a very rare scenario, but it can happen. > Maybe > upstream will always be supplied with releases from the "main" BASE, and you > can ignore this field, but it needs to be there for other firmware > distributions. > -Jeff > Sorry, I misrepresented how to the numbers would change in the above example. The change of BASE from 1 to 2 would reset MAJOR.MINOR.PATCH. So the sequence should be v1.1.0.2 -> v2.1.0.0 -> v2.1.0.1 and so on. If we don't have BASE, the pure semver.org sequence would be: v1.0.0 v1.0.1 v1.0.2 v1.0.3 v1.1.0 O--O--O--O--O \ \ \ O--O v1.1.0 v1.1.1 And so you see the duplication of version number. - Jeff > > > > > > The MAJOR number conforms to the major in semver.org. It increments on a > > > backwards incompatible change of the interface. It resets to 1 on a > > > change of > > > BASE. The MAJOR number basically works the same between the current and > > > proposed versioning schemes. > > > > > > The MINOR number conforms to the minor in semver.org. It increments on a > > > backwards compatible change of the interface (new interfaces that are > > > optional > > > to use). It will also increment on substantial new internal functionality > > > that > > > doesn't affect the interface but should be called out to the user. It > > > resets to > > > 0 on a change of MAJOR. The MINOR number in the current versioning scheme > > > increments on any backwards compatible change. The prop
Re: [Intel-gfx] [RFC] GuC firmware versioning change
On Fri, Oct 12, 2018 at 01:51:46PM -0700, Rodrigo Vivi wrote: > On Fri, Oct 12, 2018 at 01:24:30PM -0700, Jeff McGee wrote: > > The GuC firmware team is proposing a change to the firmware versioning > > scheme. > > The goal is to more accurately track the firmware interface to help users > > manage dependencies on that interface. The proposed scheme is based on > > semver.org with some additions to handle branching. > > > > The proposed version number would have 4 fields: BASE.MAJOR.MINOR.PATCH. > > Contrast this with the 2 fields in the current version number: MAJOR.MINOR. > > Side note, the current firmware encodes a BRANCH and CLIENT number as well, > > but > > they have not been needed by i915. So a firmware released with the proposed > > scheme would be named _guc_ver___.bin > > (ex: skl_guc_ver1_5_4_7.bin) instead of the current > > _guc_ver_.bin (ex: skl_guc_ver9_33.bin). > > > > The BASE number is an ID that is used to identify a set of releases in which > > the MAJOR.MINOR.PATCH semantics are consistent. In other words, two releases > > from the same BASE can be compared via their MAJOR.MINOR.PATCH to infer > > their > > relationship as described below. Two releases from a different BASE cannot > > be > > reliably compared. The BASE number facilitates arbitrary branching which can > > create duplicate and/or disconnected MAJOR.MINOR.PATCH versions. This type > > of > > branching is expected to be rare, and so BASE will rarely change. When a new > > BASE is created, the MAJOR.MINOR.PATCH reset to starting values. > > Could you please clarify a bit what BASE means? > What would be a different BASE? > The BASE number supports general branching that would cause version number conflicts. Branching for firmware releases is not desirable, but it is a practical reality. Therefore the versioning scheme must accomodate it. Let's say that a high-priority request is made to put specific updates on an old release that said customer is locked on. Those updates could include any sort of change including interface change. Then we have a sequence like below: v1.1.0.0 v1.1.0.1 v1.1.0.2 v1.1.0.3 v1.1.1.0 O--O--O--O--O \ \ \ O--O v2.1.1.0 v2.1.1.1 You can see that if we don't have a BASE number that changes from 1 to 2, then we end up with duplicated v1.1.0 along the different branches which are not the same. As I wrote, this should be a very rare scenario, but it can happen. Maybe upstream will always be supplied with releases from the "main" BASE, and you can ignore this field, but it needs to be there for other firmware distributions. -Jeff > > > > The MAJOR number conforms to the major in semver.org. It increments on a > > backwards incompatible change of the interface. It resets to 1 on a change > > of > > BASE. The MAJOR number basically works the same between the current and > > proposed versioning schemes. > > > > The MINOR number conforms to the minor in semver.org. It increments on a > > backwards compatible change of the interface (new interfaces that are > > optional > > to use). It will also increment on substantial new internal functionality > > that > > doesn't affect the interface but should be called out to the user. It > > resets to > > 0 on a change of MAJOR. The MINOR number in the current versioning scheme > > increments on any backwards compatible change. The proposed versioning > > scheme > > breaks this into the MINOR number just described and the PATCH number below. > > > > The PATCH number conforms to the patch in semver.org. It increments on a > > backwards compatible internal change, usually a bug fix. It resets to 0 on a > > change of MINOR. > > I like the idea of MAJOR.MINOR.PATCH following semver.org. > > I think if we remove the BASE out of picture and just use semver clear, > but maybe it is just because I didn't quite understand BASE. > > > > > The MAJOR.MINOR collectively define the interface version. Because the MINOR > > may also increment on a substantial internal change, it doesn't always mark > > an > > interface change, e.g. 4.5 and 4.6 may have identical interfaces. But the > > determination of interface compatibility is unchanged, e.g. 4.6 is always > > backwards compatible with 4.5. > > > > Each MAJOR.MINOR may continue to receive internal fixes along a branch even > > after the main branch for that BASE has moved
Re: [Intel-gfx] [RFC] GuC firmware versioning change
Forgot to add some people on CC. On Fri, Oct 12, 2018 at 01:24:30PM -0700, Jeff McGee wrote: > The GuC firmware team is proposing a change to the firmware versioning scheme. > The goal is to more accurately track the firmware interface to help users > manage dependencies on that interface. The proposed scheme is based on > semver.org with some additions to handle branching. > > The proposed version number would have 4 fields: BASE.MAJOR.MINOR.PATCH. > Contrast this with the 2 fields in the current version number: MAJOR.MINOR. > Side note, the current firmware encodes a BRANCH and CLIENT number as well, > but > they have not been needed by i915. So a firmware released with the proposed > scheme would be named _guc_ver___.bin > (ex: skl_guc_ver1_5_4_7.bin) instead of the current > _guc_ver_.bin (ex: skl_guc_ver9_33.bin). > > The BASE number is an ID that is used to identify a set of releases in which > the MAJOR.MINOR.PATCH semantics are consistent. In other words, two releases > from the same BASE can be compared via their MAJOR.MINOR.PATCH to infer their > relationship as described below. Two releases from a different BASE cannot be > reliably compared. The BASE number facilitates arbitrary branching which can > create duplicate and/or disconnected MAJOR.MINOR.PATCH versions. This type of > branching is expected to be rare, and so BASE will rarely change. When a new > BASE is created, the MAJOR.MINOR.PATCH reset to starting values. > > The MAJOR number conforms to the major in semver.org. It increments on a > backwards incompatible change of the interface. It resets to 1 on a change of > BASE. The MAJOR number basically works the same between the current and > proposed versioning schemes. > > The MINOR number conforms to the minor in semver.org. It increments on a > backwards compatible change of the interface (new interfaces that are optional > to use). It will also increment on substantial new internal functionality that > doesn't affect the interface but should be called out to the user. It resets > to > 0 on a change of MAJOR. The MINOR number in the current versioning scheme > increments on any backwards compatible change. The proposed versioning scheme > breaks this into the MINOR number just described and the PATCH number below. > > The PATCH number conforms to the patch in semver.org. It increments on a > backwards compatible internal change, usually a bug fix. It resets to 0 on a > change of MINOR. > > The MAJOR.MINOR collectively define the interface version. Because the MINOR > may also increment on a substantial internal change, it doesn't always mark an > interface change, e.g. 4.5 and 4.6 may have identical interfaces. But the > determination of interface compatibility is unchanged, e.g. 4.6 is always > backwards compatible with 4.5. > > Each MAJOR.MINOR may continue to receive internal fixes along a branch even > after the main branch for that BASE has moved on to another MAJOR.MINOR. > Releases from these fix-only branches increment only the PATCH number on that > MAJOR.MINOR, and therefore remain semantically consistent with the main > branch. > No change of BASE is therefore needed. Consider an example: > > v1.1.0.0 v1.1.0.1 v1.1.0.2 v1.1.1.0 v1.1.1.1 > O--O--O--O--O<-- main adopts v1.1.1.x >\ > \ > \ > O--O <-- fixes for interface > v1.1.0.x > v1.1.0.3 v1.1.0.4 > > There is no need to change the BASE because the branching happened from the > last fix (v1.1.0.2) on the main branch prior to the change of interface > (v1.1.1.0). As long as only fixes are applied to v1.1.0.x, there is no risk of > version number clash. All of these release versions remain semantically > connected with one small caveat. If this set of release versions came > sequentially along a single branch, one could infer that the exact fixes in > v1.1.0.4 were inherited by v1.1.1.0. With this "hidden" branching, this may > not be true as in this example. One would need to review the v1.1.1.0 release > notes to check. > > Please provide any feedback on the proposed change. > > Thanks, > Jeff > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC] GuC firmware versioning change
The GuC firmware team is proposing a change to the firmware versioning scheme. The goal is to more accurately track the firmware interface to help users manage dependencies on that interface. The proposed scheme is based on semver.org with some additions to handle branching. The proposed version number would have 4 fields: BASE.MAJOR.MINOR.PATCH. Contrast this with the 2 fields in the current version number: MAJOR.MINOR. Side note, the current firmware encodes a BRANCH and CLIENT number as well, but they have not been needed by i915. So a firmware released with the proposed scheme would be named _guc_ver___.bin (ex: skl_guc_ver1_5_4_7.bin) instead of the current _guc_ver_.bin (ex: skl_guc_ver9_33.bin). The BASE number is an ID that is used to identify a set of releases in which the MAJOR.MINOR.PATCH semantics are consistent. In other words, two releases from the same BASE can be compared via their MAJOR.MINOR.PATCH to infer their relationship as described below. Two releases from a different BASE cannot be reliably compared. The BASE number facilitates arbitrary branching which can create duplicate and/or disconnected MAJOR.MINOR.PATCH versions. This type of branching is expected to be rare, and so BASE will rarely change. When a new BASE is created, the MAJOR.MINOR.PATCH reset to starting values. The MAJOR number conforms to the major in semver.org. It increments on a backwards incompatible change of the interface. It resets to 1 on a change of BASE. The MAJOR number basically works the same between the current and proposed versioning schemes. The MINOR number conforms to the minor in semver.org. It increments on a backwards compatible change of the interface (new interfaces that are optional to use). It will also increment on substantial new internal functionality that doesn't affect the interface but should be called out to the user. It resets to 0 on a change of MAJOR. The MINOR number in the current versioning scheme increments on any backwards compatible change. The proposed versioning scheme breaks this into the MINOR number just described and the PATCH number below. The PATCH number conforms to the patch in semver.org. It increments on a backwards compatible internal change, usually a bug fix. It resets to 0 on a change of MINOR. The MAJOR.MINOR collectively define the interface version. Because the MINOR may also increment on a substantial internal change, it doesn't always mark an interface change, e.g. 4.5 and 4.6 may have identical interfaces. But the determination of interface compatibility is unchanged, e.g. 4.6 is always backwards compatible with 4.5. Each MAJOR.MINOR may continue to receive internal fixes along a branch even after the main branch for that BASE has moved on to another MAJOR.MINOR. Releases from these fix-only branches increment only the PATCH number on that MAJOR.MINOR, and therefore remain semantically consistent with the main branch. No change of BASE is therefore needed. Consider an example: v1.1.0.0 v1.1.0.1 v1.1.0.2 v1.1.1.0 v1.1.1.1 O--O--O--O--O<-- main adopts v1.1.1.x \ \ \ O--O <-- fixes for interface v1.1.0.x v1.1.0.3 v1.1.0.4 There is no need to change the BASE because the branching happened from the last fix (v1.1.0.2) on the main branch prior to the change of interface (v1.1.1.0). As long as only fixes are applied to v1.1.0.x, there is no risk of version number clash. All of these release versions remain semantically connected with one small caveat. If this set of release versions came sequentially along a single branch, one could infer that the exact fixes in v1.1.0.4 were inherited by v1.1.1.0. With this "hidden" branching, this may not be true as in this example. One would need to review the v1.1.1.0 release notes to check. Please provide any feedback on the proposed change. Thanks, Jeff ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915/guc: Disable preemption if it fails
On Thu, May 31, 2018 at 10:20:54PM +0100, Chris Wilson wrote: > Quoting Singh, Satyeshwar (2018-05-31 22:17:25) > > Hi Chris, > > Isn't this dependent upon the workload submitted to the GuC? Meaning we > > have one workload that refused to be preempted (really long shader for > > example) but it went away on its own. Other workloads that come in later > > are preemptible. However, if we turn off preemption permanently, then all > > future workloads will not be preempted either which may not be desirable. > > Whoever implements the recovery mechanism can clear the flag. You may > like to clear the flag on reset? We would have to be more careful about > the manipulation of engine->flags as it's not serialised atm (since it's > _meant_ to be write-once during init). > -Chris The error that would occur here is a failure of GuC to *initiate* the preemption, and is different from a slow resolution of the preemption on hardware caused by the workload blocking scenario that Satyeshwar describes. GuC will wait forever for preemption resolution, as will i915 currently without a timeout mechanism. A failure of GuC to initiate a preemption would be a very strange and bad thing and probably would warrant a WARN and disabling. Is anyone actually seeing that with current firmware? I have not in my own testing. Is it an actual error returned from GuC or a timeout waiting for GuC response? -Jeff ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 08/11] drm/i915/execlists: Force preemption via reset on timeout
On Mon, Mar 26, 2018 at 12:50:41PM +0100, Chris Wilson wrote: > Install a timer when trying to preempt on behalf of an important > context such that if the active context does not honour the preemption > request within the desired timeout, then we reset the GPU to allow the > important context to run. > > (Open: should not the timer be started from receiving the high priority > request...) > > Signed-off-by: Chris Wilson > --- > drivers/gpu/drm/i915/intel_lrc.c| 53 > + > drivers/gpu/drm/i915/intel_ringbuffer.h | 8 + > 2 files changed, 61 insertions(+) > > diff --git a/drivers/gpu/drm/i915/intel_lrc.c > b/drivers/gpu/drm/i915/intel_lrc.c > index 50688fc889d9..6da816d23cb3 100644 > --- a/drivers/gpu/drm/i915/intel_lrc.c > +++ b/drivers/gpu/drm/i915/intel_lrc.c > @@ -533,6 +533,47 @@ static void inject_preempt_context(struct > intel_engine_cs *engine) > > execlists_clear_active(execlists, EXECLISTS_ACTIVE_HWACK); > execlists_set_active(execlists, EXECLISTS_ACTIVE_PREEMPT); > + > + /* Set a timer to force preemption vs hostile userspace */ > + if (execlists->queue_preempt_timeout) { > + GEM_TRACE("%s timeout=%uns\n", > + engine->name, execlists->queue_preempt_timeout); > + hrtimer_start(&execlists->preempt_timer, > + ktime_set(0, execlists->queue_preempt_timeout), > + HRTIMER_MODE_REL); > + } > +} > + > +static enum hrtimer_restart preempt_timeout(struct hrtimer *hrtimer) > +{ > + struct intel_engine_execlists *execlists = > + container_of(hrtimer, typeof(*execlists), preempt_timer); > + > + GEM_TRACE("%s\n", > + container_of(execlists, > +struct intel_engine_cs, > +execlists)->name); > + > + queue_work(system_highpri_wq, &execlists->preempt_reset); > + return HRTIMER_NORESTART; > +} > + > +static void preempt_reset(struct work_struct *work) > +{ > + struct intel_engine_cs *engine = > + container_of(work, typeof(*engine), execlists.preempt_reset); > + > + GEM_TRACE("%s\n", engine->name); > + > + tasklet_disable(&engine->execlists.tasklet); > + > + engine->execlists.tasklet.func(engine->execlists.tasklet.data); This seems redundant with the execlists_reset_prepare already doing a process_csb at a later time to decide whether to execute or abort the reset. In your previous proposal you suggested tasklet disable and kill here. > + > + if (execlists_is_active(&engine->execlists, EXECLISTS_ACTIVE_PREEMPT)) > + i915_handle_error(engine->i915, BIT(engine->id), 0, > + "preemption timed out on %s", engine->name); > + > + tasklet_enable(&engine->execlists.tasklet); > } > > static void complete_preempt_context(struct intel_engine_execlists > *execlists) > @@ -542,6 +583,10 @@ static void complete_preempt_context(struct > intel_engine_execlists *execlists) > execlists_cancel_port_requests(execlists); > execlists_unwind_incomplete_requests(execlists); > > + /* If the timer already fired, complete the reset */ > + if (hrtimer_try_to_cancel(&execlists->preempt_timer) < 0) > + return; > + > execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT); > } > > @@ -708,6 +753,7 @@ static void execlists_dequeue(struct intel_engine_cs > *engine) > kmem_cache_free(engine->i915->priorities, p); > } > done: > + execlists->queue_preempt_timeout = 0; /* preemption point passed */ > execlists->queue_priority = rb ? to_priolist(rb)->priority : INT_MIN; > execlists->first = rb; > if (submit) > @@ -864,6 +910,7 @@ static void execlists_cancel_requests(struct > intel_engine_cs *engine) > > /* Remaining _unready_ requests will be nop'ed when submitted */ > > + execlists->queue_preempt_timeout = 0; > execlists->queue_priority = INT_MIN; > execlists->queue = RB_ROOT; > execlists->first = NULL; > @@ -1080,6 +1127,7 @@ static void queue_request(struct intel_engine_cs > *engine, > static void __submit_queue(struct intel_engine_cs *engine, int prio) > { > engine->execlists.queue_priority = prio; > + engine->execlists.queue_preempt_timeout = 0; > tasklet_hi_schedule(&engine->execlists.tasklet); > } > > @@ -2270,6 +2318,11 @@ logical_ring_setup(struct intel_engine_cs *engine) > tasklet_init(&engine->execlists.tasklet, >execlists_submission_tasklet, (unsigned long)engine); > > + INIT_WORK(&engine->execlists.preempt_reset, preempt_reset); > + hrtimer_init(&engine->execlists.preempt_timer, > + CLOCK_MONOTONIC, HRTIMER_MODE_REL); > + engine->execlists.preempt_timer.function = preempt_timeout; > + > logical_ring_default_vfuncs(engine); > logical_ring_default_i
Re: [Intel-gfx] [PATCH 08/11] drm/i915/execlists: Force preemption via reset on timeout
On Tue, Mar 27, 2018 at 09:51:20AM +0100, Tvrtko Ursulin wrote: > > On 26/03/2018 12:50, Chris Wilson wrote: > >Install a timer when trying to preempt on behalf of an important > >context such that if the active context does not honour the preemption > >request within the desired timeout, then we reset the GPU to allow the > >important context to run. > > I suggest renaming patch title to "Implement optional preemption > delay timeout", or "upper bound", or something, as long as it is not > "force preemption". :) > > >(Open: should not the timer be started from receiving the high priority > >request...) > > If you think receiving as in execbuf I think not - that would be > something else and not preempt timeout. > > >Signed-off-by: Chris Wilson > >--- > > drivers/gpu/drm/i915/intel_lrc.c| 53 > > + > > drivers/gpu/drm/i915/intel_ringbuffer.h | 8 + > > 2 files changed, 61 insertions(+) > > > >diff --git a/drivers/gpu/drm/i915/intel_lrc.c > >b/drivers/gpu/drm/i915/intel_lrc.c > >index 50688fc889d9..6da816d23cb3 100644 > >--- a/drivers/gpu/drm/i915/intel_lrc.c > >+++ b/drivers/gpu/drm/i915/intel_lrc.c > >@@ -533,6 +533,47 @@ static void inject_preempt_context(struct > >intel_engine_cs *engine) > > execlists_clear_active(execlists, EXECLISTS_ACTIVE_HWACK); > > execlists_set_active(execlists, EXECLISTS_ACTIVE_PREEMPT); > >+ > >+/* Set a timer to force preemption vs hostile userspace */ > >+if (execlists->queue_preempt_timeout) { > >+GEM_TRACE("%s timeout=%uns\n", > > preempt-timeout ? > > >+ engine->name, execlists->queue_preempt_timeout); > >+hrtimer_start(&execlists->preempt_timer, > >+ ktime_set(0, execlists->queue_preempt_timeout), > >+ HRTIMER_MODE_REL); > >+} > >+} > >+ > >+static enum hrtimer_restart preempt_timeout(struct hrtimer *hrtimer) > >+{ > >+struct intel_engine_execlists *execlists = > >+container_of(hrtimer, typeof(*execlists), preempt_timer); > >+ > >+GEM_TRACE("%s\n", > >+ container_of(execlists, > >+ struct intel_engine_cs, > >+ execlists)->name); > >+ > >+queue_work(system_highpri_wq, &execlists->preempt_reset); > > I suppose indirection from hrtimer to worker is for better than > jiffie timeout granularity? But then queue_work might introduce some > delay to defeat that. > > I am wondering if simply schedule_delayed_work directly wouldn't be > good enough. I suppose it is a question for the product group. But > it is also implementation detail. > I started with schedule_delayed_work in my implementation hoping for at least consistent msec accuracy, but it was all over the place. We need msec granularity for the automotive use cases. -Jeff > >+return HRTIMER_NORESTART; > >+} > >+ > >+static void preempt_reset(struct work_struct *work) > >+{ > >+struct intel_engine_cs *engine = > >+container_of(work, typeof(*engine), execlists.preempt_reset); > >+ > >+GEM_TRACE("%s\n", engine->name); > >+ > >+tasklet_disable(&engine->execlists.tasklet); > >+ > >+engine->execlists.tasklet.func(engine->execlists.tasklet.data); > > Comment on why calling the tasklet directly. > > >+ > >+if (execlists_is_active(&engine->execlists, EXECLISTS_ACTIVE_PREEMPT)) > >+i915_handle_error(engine->i915, BIT(engine->id), 0, > >+ "preemption timed out on %s", engine->name); > > Can this race with the normal reset and we end up wit > i915_handle_error twice simultaneously? > > >+ > >+tasklet_enable(&engine->execlists.tasklet); > > } > > static void complete_preempt_context(struct intel_engine_execlists > > *execlists) > >@@ -542,6 +583,10 @@ static void complete_preempt_context(struct > >intel_engine_execlists *execlists) > > execlists_cancel_port_requests(execlists); > > execlists_unwind_incomplete_requests(execlists); > >+/* If the timer already fired, complete the reset */ > >+if (hrtimer_try_to_cancel(&execlists->preempt_timer) < 0) > >+return; > > What about timer which had already fired and queued the worker? > hrtimer_try_to_cancel will return zero for that case I think. > > >+ > > execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT); > > } > >@@ -708,6 +753,7 @@ static void execlists_dequeue(struct intel_engine_cs > >*engine) > > kmem_cache_free(engine->i915->priorities, p); > > } > > done: > >+execlists->queue_preempt_timeout = 0; /* preemption point passed */ > > execlists->queue_priority = rb ? to_priolist(rb)->priority : INT_MIN; > > execlists->first = rb; > > if (submit) > >@@ -864,6 +910,7 @@ static void execlists_cancel_requests(struct > >intel_engine_cs *engine) > > /* Remaining _unready_ requests will be nop'ed when submitted */ > >+execlists->queue_preempt_timeout = 0;
Re: [Intel-gfx] [PATCH v2] drm/i915/execlists: Flush pending preemption events during reset
On Tue, Mar 27, 2018 at 12:44:02PM +0100, Chris Wilson wrote: > Catch up with the inflight CSB events, after disabling the tasklet > before deciding which request was truly guilty of hanging the GPU. > > v2: Restore checking of use_csb_mmio on every loop, don't forget old > vgpu. > > Signed-off-by: Chris Wilson > Cc: Michał Winiarski > CC: Michel Thierry > Cc: Jeff McGee > --- > drivers/gpu/drm/i915/intel_lrc.c | 127 > +++ > 1 file changed, 87 insertions(+), 40 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_lrc.c > b/drivers/gpu/drm/i915/intel_lrc.c > index cf31b0749023..75dbdedde8b0 100644 > --- a/drivers/gpu/drm/i915/intel_lrc.c > +++ b/drivers/gpu/drm/i915/intel_lrc.c > @@ -874,34 +874,14 @@ static void execlists_cancel_requests(struct > intel_engine_cs *engine) > local_irq_restore(flags); > } > > -/* > - * Check the unread Context Status Buffers and manage the submission of new > - * contexts to the ELSP accordingly. > - */ > -static void execlists_submission_tasklet(unsigned long data) > +static void process_csb(struct intel_engine_cs *engine) > { > - struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; > struct intel_engine_execlists * const execlists = &engine->execlists; > struct execlist_port * const port = execlists->port; > - struct drm_i915_private *dev_priv = engine->i915; > + struct drm_i915_private *i915 = engine->i915; > bool fw = false; > > - /* > - * We can skip acquiring intel_runtime_pm_get() here as it was taken > - * on our behalf by the request (see i915_gem_mark_busy()) and it will > - * not be relinquished until the device is idle (see > - * i915_gem_idle_work_handler()). As a precaution, we make sure > - * that all ELSP are drained i.e. we have processed the CSB, > - * before allowing ourselves to idle and calling intel_runtime_pm_put(). > - */ > - GEM_BUG_ON(!dev_priv->gt.awake); > - > - /* > - * Prefer doing test_and_clear_bit() as a two stage operation to avoid > - * imposing the cost of a locked atomic transaction when submitting a > - * new request (outside of the context-switch interrupt). > - */ > - while (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) { > + do { Wouldn't it be simpler for process_csb to use a while loop here, and for callers that need a CSB processing point to just call it without themselves checking irq_posted? Are we really saving much with the if-do-while approach? > /* The HWSP contains a (cacheable) mirror of the CSB */ > const u32 *buf = > &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; > @@ -909,28 +889,27 @@ static void execlists_submission_tasklet(unsigned long > data) > > if (unlikely(execlists->csb_use_mmio)) { > buf = (u32 * __force) > - (dev_priv->regs + > i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); > - execlists->csb_head = -1; /* force mmio read of CSB > ptrs */ > + (i915->regs + > i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); > + execlists->csb_head = -1; /* force mmio read of CSB */ > } > > /* Clear before reading to catch new interrupts */ > clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); > smp_mb__after_atomic(); > > - if (unlikely(execlists->csb_head == -1)) { /* following a reset > */ > + if (unlikely(execlists->csb_head == -1)) { /* after a reset */ > if (!fw) { > - intel_uncore_forcewake_get(dev_priv, > - > execlists->fw_domains); > + intel_uncore_forcewake_get(i915, > execlists->fw_domains); > fw = true; > } > > - head = readl(dev_priv->regs + > i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); > + head = readl(i915->regs + > i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); > tail = GEN8_CSB_WRITE_PTR(head); > head = GEN8_CSB_READ_PTR(head); > execlists->csb_head = head; > } else { > const int write_idx = > - intel_hws_csb_write_index(dev_priv) - > +
Re: [Intel-gfx] [PATCH v2] drm/i915/selftests: Include the trace as a debug aide
On Thu, Mar 22, 2018 at 02:30:09PM +, Chris Wilson wrote: > Quoting Mika Kuoppala (2018-03-22 14:26:41) > > Chris Wilson writes: > > > > > If we fail to reset the GPU in a timely fashion, dump the GEM trace so > > > that we can see what operations were in flight when the GPU got stuck. > > > > > > v2: There's more than one timeout that deserves tracing! > > > v3: Silence checkpatch by not even using a product at all! > > > > > > Signed-off-by: Chris Wilson > > > --- > > > drivers/gpu/drm/i915/selftests/intel_hangcheck.c | 23 > > > --- > > > 1 file changed, 20 insertions(+), 3 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c > > > b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c > > > index 4372826998aa..9b235dae8dd9 100644 > > > --- a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c > > > +++ b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c > > > @@ -260,8 +260,11 @@ static void wedge_me(struct work_struct *work) > > > { > > > struct wedge_me *w = container_of(work, typeof(*w), work.work); > > > > > > - pr_err("%pS timed out, cancelling all further testing.\n", > > > -w->symbol); > > > + pr_err("%pS timed out, cancelling all further testing.\n", > > > w->symbol); > > > + > > > + GEM_TRACE("%pS timed out.\n", w->symbol); > > > + GEM_TRACE_DUMP(); > > > + > > > i915_gem_set_wedged(w->i915); > > > } > > > > > > @@ -621,9 +624,19 @@ static int active_engine(void *data) > > > mutex_unlock(&engine->i915->drm.struct_mutex); > > > > > > if (old) { > > > - i915_request_wait(old, 0, MAX_SCHEDULE_TIMEOUT); > > > + if (i915_request_wait(old, 0, HZ) < 0) { > > > + GEM_TRACE("%s timed out.\n", engine->name); > > > + GEM_TRACE_DUMP(); > > > + > > > + i915_gem_set_wedged(engine->i915); > > > + i915_request_put(old); > > > + err = -EIO; > > > + break; > > > + } > > > > Using err = i915_request_wait() could have saved one extra request_put > > but I dunno if it would be any cleaner. > > It's also -ETIME, which didn't fit my intention. > > > > > > i915_request_put(old); > > > } > > > + > > > + cond_resched(); > > > > To give more slack for other engines and main thread to proceed? > > Yes. Otherwise, it spins mighty fine. > > > > > } > > > > > > for (count = 0; count < ARRAY_SIZE(rq); count++) > > > @@ -1126,6 +1139,10 @@ int intel_hangcheck_live_selftests(struct > > > drm_i915_private *i915) > > > > > > err = i915_subtests(tests, i915); > > > > > > + mutex_lock(&i915->drm.struct_mutex); > > > + flush_test(i915, I915_WAIT_LOCKED); > > > + mutex_unlock(&i915->drm.struct_mutex); > > > + > > > > To wash out leftovers. > > Yeah, from the early abort we left requests unaccounted for and needed > to grab the struct_mutex to run retire. Otherwise we hit assertions > later on about trying to unload the driver with requests still inflight. > -Chris On this and the 3 others in this series... Reviewed-by: Jeff McGee ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC 0/8] Force preemption
On Thu, Mar 22, 2018 at 05:41:57PM +, Tvrtko Ursulin wrote: > > On 22/03/2018 16:01, Jeff McGee wrote: > >On Thu, Mar 22, 2018 at 03:57:49PM +, Tvrtko Ursulin wrote: > >> > >>On 22/03/2018 14:34, Jeff McGee wrote: > >>>On Thu, Mar 22, 2018 at 09:28:00AM +, Chris Wilson wrote: > >>>>Quoting Tvrtko Ursulin (2018-03-22 09:22:55) > >>>>> > >>>>>On 21/03/2018 17:26, jeff.mc...@intel.com wrote: > >>>>>>From: Jeff McGee > >>>>>> > >>>>>>Force preemption uses engine reset to enforce a limit on the time > >>>>>>that a request targeted for preemption can block. This feature is > >>>>>>a requirement in automotive systems where the GPU may be shared by > >>>>>>clients of critically high priority and clients of low priority that > >>>>>>may not have been curated to be preemption friendly. There may be > >>>>>>more general applications of this feature. I'm sharing as an RFC to > >>>>>>stimulate that discussion and also to get any technical feedback > >>>>>>that I can before submitting to the product kernel that needs this. > >>>>>>I have developed the patches for ease of rebase, given that this is > >>>>>>for the moment considered a non-upstreamable feature. It would be > >>>>>>possible to refactor hangcheck to fully incorporate force preemption > >>>>>>as another tier of patience (or impatience) with the running request. > >>>>> > >>>>>Sorry if it was mentioned elsewhere and I missed it - but does this work > >>>>>only with stateless clients - or in other words, what would happen to > >>>>>stateful clients which would be force preempted? Or the answer is we > >>>>>don't care since they are misbehaving? > >>>> > >>>>They get notified of being guilty for causing a gpu reset; three strikes > >>>>and they are out (banned from using the gpu) using the current rules. > >>>>This is a very blunt hammer that requires the rest of the system to be > >>>>robust; one might argue time spent making the system robust would be > >>>>better served making sure that the timer never expired in the first place > >>>>thereby eliminating the need for a forced gpu reset. > >>>>-Chris > >>> > >>>Yes, for simplication the policy applied to force preempted contexts > >>>is the same as for hanging contexts. It is known that this feature > >>>should not be required in a fully curated system. It's a requirement > >>>if end user will be alllowed to install 3rd party apps to run in the > >>>non-critical domain. > >> > >>My concern is whether it safe to call this force _preemption_, while > >>it is not really expected to work as preemption from the point of > >>view of preempted context. I may be missing some angle here, but I > >>think a better name would include words like maximum request > >>duration or something. > >> > >>I can see a difference between allowed maximum duration when there > >>is something else pending, and when it isn't, but I don't > >>immediately see that we should consider this distinction for any > >>real benefit? > >> > >>So should the feature just be "maximum request duration"? This would > >>perhaps make it just a special case of hangcheck, which ignores head > >>progress, or whatever we do in there. > >> > >>Regards, > >> > >>Tvrtko > > > >I think you might be unclear about how this works. We're not starting a > >preemption to see if we can cleanly remove a request who has begun to > >exceed its normal time slice, i.e. hangcheck. This is about bounding > >the time that a normal preemption can take. So first start preemption > >in response to higher-priority request arrival, then wait for preemption > >to complete within a certain amount of time. If it does not, resort to > >reset. > > > >So it's really "force the resolution of a preemption", shortened to > >"force preemption". > > You are right, I veered off in my thinking and ended up with > something different. :) > > I however still think the name is potentially misleading, since the > request/context is not getting preempted. It is getting effectively > killed (sooner or later,
Re: [Intel-gfx] [RFC 0/8] Force preemption
On Thu, Mar 22, 2018 at 03:57:49PM +, Tvrtko Ursulin wrote: > > On 22/03/2018 14:34, Jeff McGee wrote: > >On Thu, Mar 22, 2018 at 09:28:00AM +, Chris Wilson wrote: > >>Quoting Tvrtko Ursulin (2018-03-22 09:22:55) > >>> > >>>On 21/03/2018 17:26, jeff.mc...@intel.com wrote: > >>>>From: Jeff McGee > >>>> > >>>>Force preemption uses engine reset to enforce a limit on the time > >>>>that a request targeted for preemption can block. This feature is > >>>>a requirement in automotive systems where the GPU may be shared by > >>>>clients of critically high priority and clients of low priority that > >>>>may not have been curated to be preemption friendly. There may be > >>>>more general applications of this feature. I'm sharing as an RFC to > >>>>stimulate that discussion and also to get any technical feedback > >>>>that I can before submitting to the product kernel that needs this. > >>>>I have developed the patches for ease of rebase, given that this is > >>>>for the moment considered a non-upstreamable feature. It would be > >>>>possible to refactor hangcheck to fully incorporate force preemption > >>>>as another tier of patience (or impatience) with the running request. > >>> > >>>Sorry if it was mentioned elsewhere and I missed it - but does this work > >>>only with stateless clients - or in other words, what would happen to > >>>stateful clients which would be force preempted? Or the answer is we > >>>don't care since they are misbehaving? > >> > >>They get notified of being guilty for causing a gpu reset; three strikes > >>and they are out (banned from using the gpu) using the current rules. > >>This is a very blunt hammer that requires the rest of the system to be > >>robust; one might argue time spent making the system robust would be > >>better served making sure that the timer never expired in the first place > >>thereby eliminating the need for a forced gpu reset. > >>-Chris > > > >Yes, for simplication the policy applied to force preempted contexts > >is the same as for hanging contexts. It is known that this feature > >should not be required in a fully curated system. It's a requirement > >if end user will be alllowed to install 3rd party apps to run in the > >non-critical domain. > > My concern is whether it safe to call this force _preemption_, while > it is not really expected to work as preemption from the point of > view of preempted context. I may be missing some angle here, but I > think a better name would include words like maximum request > duration or something. > > I can see a difference between allowed maximum duration when there > is something else pending, and when it isn't, but I don't > immediately see that we should consider this distinction for any > real benefit? > > So should the feature just be "maximum request duration"? This would > perhaps make it just a special case of hangcheck, which ignores head > progress, or whatever we do in there. > > Regards, > > Tvrtko I think you might be unclear about how this works. We're not starting a preemption to see if we can cleanly remove a request who has begun to exceed its normal time slice, i.e. hangcheck. This is about bounding the time that a normal preemption can take. So first start preemption in response to higher-priority request arrival, then wait for preemption to complete within a certain amount of time. If it does not, resort to reset. So it's really "force the resolution of a preemption", shortened to "force preemption". -Jeff ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC 0/8] Force preemption
On Thu, Mar 22, 2018 at 03:35:19PM +, Chris Wilson wrote: > Quoting Jeff McGee (2018-03-22 14:34:58) > > On Thu, Mar 22, 2018 at 09:28:00AM +, Chris Wilson wrote: > > > Quoting Tvrtko Ursulin (2018-03-22 09:22:55) > > > > > > > > On 21/03/2018 17:26, jeff.mc...@intel.com wrote: > > > > > From: Jeff McGee > > > > > > > > > > Force preemption uses engine reset to enforce a limit on the time > > > > > that a request targeted for preemption can block. This feature is > > > > > a requirement in automotive systems where the GPU may be shared by > > > > > clients of critically high priority and clients of low priority that > > > > > may not have been curated to be preemption friendly. There may be > > > > > more general applications of this feature. I'm sharing as an RFC to > > > > > stimulate that discussion and also to get any technical feedback > > > > > that I can before submitting to the product kernel that needs this. > > > > > I have developed the patches for ease of rebase, given that this is > > > > > for the moment considered a non-upstreamable feature. It would be > > > > > possible to refactor hangcheck to fully incorporate force preemption > > > > > as another tier of patience (or impatience) with the running request. > > > > > > > > Sorry if it was mentioned elsewhere and I missed it - but does this > > > > work > > > > only with stateless clients - or in other words, what would happen to > > > > stateful clients which would be force preempted? Or the answer is we > > > > don't care since they are misbehaving? > > > > > > They get notified of being guilty for causing a gpu reset; three strikes > > > and they are out (banned from using the gpu) using the current rules. > > > This is a very blunt hammer that requires the rest of the system to be > > > robust; one might argue time spent making the system robust would be > > > better served making sure that the timer never expired in the first place > > > thereby eliminating the need for a forced gpu reset. > > > -Chris > > > > Yes, for simplication the policy applied to force preempted contexts > > is the same as for hanging contexts. It is known that this feature > > should not be required in a fully curated system. It's a requirement > > if end user will be alllowed to install 3rd party apps to run in the > > non-critical domain. > > Third party code is still mediated by our userspace drivers, or are you > contemplating scenarios where they talk directly to ioctls? How hostile > do we have to contend with, i.e. survive a gpu fork bomb? > -Chris User space driver has very little influence over the preemptibility of the user space app. The most it can do is enable the finest granularity, e.g. 3D object level. But app can still submit a single giant triangle with uber pixelshader. Nothing overtly wrong with that, but it is not mid-batch preemptible on our hardware. -Jeff ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 3/4] drm/i915: Use full serialisation around engine->irq_posted
On Thu, Mar 22, 2018 at 07:35:32AM +, Chris Wilson wrote: > Using engine->irq_posted for execlists, we are not always serialised by > the tasklet as we supposed. On the reset paths, the tasklet is disabled > and ignored. Instead, we manipulate the engine->irq_posted directly to > account for the reset, but if an interrupt fired before the reset and so > wrote to engine->irq_posted, that write may not be flushed from the > local CPU's cacheline until much later as the tasklet is already active > and so does not generate a mb(). To correctly serialise the interrupt > with reset, we need serialisation on the set_bit() itself. > > And at last Mika can be happy. > > Signed-off-by: Chris Wilson > Cc: Mika Kuoppala > Cc: Michał Winiarski > CC: Michel Thierry > Cc: Jeff McGee > Cc: Tvrtko Ursulin > --- > drivers/gpu/drm/i915/i915_irq.c | 7 +++ > 1 file changed, 3 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > index fa7310766217..27aee25429b7 100644 > --- a/drivers/gpu/drm/i915/i915_irq.c > +++ b/drivers/gpu/drm/i915/i915_irq.c > @@ -1405,10 +1405,9 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, > u32 iir) > bool tasklet = false; > > if (iir & GT_CONTEXT_SWITCH_INTERRUPT) { > - if (READ_ONCE(engine->execlists.active)) { > - __set_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); > - tasklet = true; > - } > + if (READ_ONCE(engine->execlists.active)) > + tasklet = !test_and_set_bit(ENGINE_IRQ_EXECLIST, > + &engine->irq_posted); > } > > if (iir & GT_RENDER_USER_INTERRUPT) { > -- > 2.16.2 > Confirmed that this along with the interrupt flush eliminates the cases of finding CSB tail at its reset value (0x7) in the tasklet in my force preemption tests. Reviewed-by: Jeff McGee ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 4/5] drm/i915: Split execlists/guc reset prepartions
On Tue, Mar 20, 2018 at 12:18:47AM +, Chris Wilson wrote: > In the next patch, we will make the execlists reset prepare callback > take into account preemption by flushing the context-switch handler. > This is not applicable to the GuC submission backend, so split the two > into their own backend callbacks. > > Signed-off-by: Chris Wilson > Cc: Michał Winiarski > CC: Michel Thierry > Cc: Jeff McGee > --- > drivers/gpu/drm/i915/intel_guc_submission.c | 39 > + > drivers/gpu/drm/i915/intel_lrc.c| 11 +--- > 2 files changed, 40 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c > b/drivers/gpu/drm/i915/intel_guc_submission.c > index 207cda062626..779c8d3156e5 100644 > --- a/drivers/gpu/drm/i915/intel_guc_submission.c > +++ b/drivers/gpu/drm/i915/intel_guc_submission.c > @@ -776,6 +776,44 @@ static void guc_submission_tasklet(unsigned long data) > guc_dequeue(engine); > } > > +static struct i915_request * > +guc_reset_prepare(struct intel_engine_cs *engine) > +{ > + struct intel_engine_execlists * const execlists = &engine->execlists; > + > + /* > + * Prevent request submission to the hardware until we have > + * completed the reset in i915_gem_reset_finish(). If a request > + * is completed by one engine, it may then queue a request > + * to a second via its execlists->tasklet *just* as we are > + * calling engine->init_hw() and also writing the ELSP. > + * Turning off the execlists->tasklet until the reset is over > + * prevents the race. > + * > + * Note that this needs to be a single atomic operation on the > + * tasklet (flush existing tasks, prevent new tasks) to prevent > + * a race between reset and set-wedged. It is not, so we do the best > + * we can atm and make sure we don't lock the machine up in the more > + * common case of recursively being called from set-wedged from inside > + * i915_reset. > + */ > + if (!atomic_read(&execlists->tasklet.count)) > + tasklet_kill(&execlists->tasklet); > + tasklet_disable(&execlists->tasklet); > + > + /* > + * We're using worker to queue preemption requests from the tasklet in > + * GuC submission mode. > + * Even though tasklet was disabled, we may still have a worker queued. > + * Let's make sure that all workers scheduled before disabling the > + * tasklet are completed before continuing with the reset. > + */ > + if (engine->i915->guc.preempt_wq) > + flush_workqueue(engine->i915->guc.preempt_wq); > + > + return i915_gem_find_active_request(engine); > +} > + > /* > * Everything below here is concerned with setup & teardown, and is > * therefore not part of the somewhat time-critical batch-submission > @@ -1235,6 +1273,7 @@ int intel_guc_submission_enable(struct intel_guc *guc) > &engine->execlists; > > execlists->tasklet.func = guc_submission_tasklet; > + engine->reset.prepare = guc_reset_prepare; > engine->park = guc_submission_park; > engine->unpark = guc_submission_unpark; > > diff --git a/drivers/gpu/drm/i915/intel_lrc.c > b/drivers/gpu/drm/i915/intel_lrc.c > index f662a9524233..e5a3ffbc273a 100644 > --- a/drivers/gpu/drm/i915/intel_lrc.c > +++ b/drivers/gpu/drm/i915/intel_lrc.c > @@ -1688,16 +1688,6 @@ execlists_reset_prepare(struct intel_engine_cs *engine) > tasklet_kill(&execlists->tasklet); > tasklet_disable(&execlists->tasklet); > > - /* > - * We're using worker to queue preemption requests from the tasklet in > - * GuC submission mode. > - * Even though tasklet was disabled, we may still have a worker queued. > - * Let's make sure that all workers scheduled before disabling the > - * tasklet are completed before continuing with the reset. > - */ > - if (engine->i915->guc.preempt_wq) > - flush_workqueue(engine->i915->guc.preempt_wq); > - > return i915_gem_find_active_request(engine); > } > > @@ -2115,6 +2105,7 @@ static void execlists_set_default_submission(struct > intel_engine_cs *engine) > engine->cancel_requests = execlists_cancel_requests; > engine->schedule = execlists_schedule; > engine->execlists.tasklet.func = execlists_submission_tasklet; > + engine->reset.prepare = execlists_reset_prepare; > > engine->park = NULL; > engine->unpark = NULL; > -- > 2.16.2 > Reviewed-by: Jeff McGee ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 3/5] drm/i915: Move engine reset prepare/finish to backends
On Tue, Mar 20, 2018 at 12:18:46AM +, Chris Wilson wrote: > In preparation to more carefully handling incomplete preemption during > reset by execlists, we move the existing code wholesale to the backends > under a couple of new reset vfuncs. > > Signed-off-by: Chris Wilson > Cc: Michał Winiarski > CC: Michel Thierry > Cc: Jeff McGee > --- > drivers/gpu/drm/i915/i915_gem.c | 42 -- > drivers/gpu/drm/i915/intel_lrc.c| 52 > +++-- > drivers/gpu/drm/i915/intel_ringbuffer.c | 20 +++-- > drivers/gpu/drm/i915/intel_ringbuffer.h | 9 -- > 4 files changed, 78 insertions(+), 45 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c > index 802df8e1a544..38f7160d99c9 100644 > --- a/drivers/gpu/drm/i915/i915_gem.c > +++ b/drivers/gpu/drm/i915/i915_gem.c > @@ -2917,7 +2917,7 @@ static bool engine_stalled(struct intel_engine_cs > *engine) > struct i915_request * > i915_gem_reset_prepare_engine(struct intel_engine_cs *engine) > { > - struct i915_request *request = NULL; > + struct i915_request *request; > > /* >* During the reset sequence, we must prevent the engine from > @@ -2940,40 +2940,7 @@ i915_gem_reset_prepare_engine(struct intel_engine_cs > *engine) >*/ > kthread_park(engine->breadcrumbs.signaler); > > - /* > - * Prevent request submission to the hardware until we have > - * completed the reset in i915_gem_reset_finish(). If a request > - * is completed by one engine, it may then queue a request > - * to a second via its execlists->tasklet *just* as we are > - * calling engine->init_hw() and also writing the ELSP. > - * Turning off the execlists->tasklet until the reset is over > - * prevents the race. > - * > - * Note that this needs to be a single atomic operation on the > - * tasklet (flush existing tasks, prevent new tasks) to prevent > - * a race between reset and set-wedged. It is not, so we do the best > - * we can atm and make sure we don't lock the machine up in the more > - * common case of recursively being called from set-wedged from inside > - * i915_reset. > - */ > - if (!atomic_read(&engine->execlists.tasklet.count)) > - tasklet_kill(&engine->execlists.tasklet); > - tasklet_disable(&engine->execlists.tasklet); > - > - /* > - * We're using worker to queue preemption requests from the tasklet in > - * GuC submission mode. > - * Even though tasklet was disabled, we may still have a worker queued. > - * Let's make sure that all workers scheduled before disabling the > - * tasklet are completed before continuing with the reset. > - */ > - if (engine->i915->guc.preempt_wq) > - flush_workqueue(engine->i915->guc.preempt_wq); > - > - if (engine->irq_seqno_barrier) > - engine->irq_seqno_barrier(engine); > - > - request = i915_gem_find_active_request(engine); > + request = engine->reset.prepare(engine); > if (request && request->fence.error == -EIO) > request = ERR_PTR(-EIO); /* Previous reset failed! */ > > @@ -3120,7 +3087,7 @@ void i915_gem_reset_engine(struct intel_engine_cs > *engine, > } > > /* Setup the CS to resume from the breadcrumb of the hung request */ > - engine->reset_hw(engine, request); > + engine->reset.reset(engine, request); > } > > void i915_gem_reset(struct drm_i915_private *dev_priv) > @@ -3172,7 +3139,8 @@ void i915_gem_reset(struct drm_i915_private *dev_priv) > > void i915_gem_reset_finish_engine(struct intel_engine_cs *engine) > { > - tasklet_enable(&engine->execlists.tasklet); > + engine->reset.finish(engine); > + > kthread_unpark(engine->breadcrumbs.signaler); > > intel_uncore_forcewake_put(engine->i915, FORCEWAKE_ALL); > diff --git a/drivers/gpu/drm/i915/intel_lrc.c > b/drivers/gpu/drm/i915/intel_lrc.c > index 0bfaeb56b8c7..f662a9524233 100644 > --- a/drivers/gpu/drm/i915/intel_lrc.c > +++ b/drivers/gpu/drm/i915/intel_lrc.c > @@ -1663,6 +1663,44 @@ static int gen9_init_render_ring(struct > intel_engine_cs *engine) > return init_workarounds_ring(engine); > } > > +static struct i915_request * > +execlists_reset_prepare(struct intel_engine_cs *engine) > +{ > + struct intel_engine_execlists * const execlists = &engine->execlists; > + > + /* > + * Prevent request submission to the hardware until we have >
Re: [Intel-gfx] [PATCH 2/5] drm/i915/execlists: Refactor out complete_preempt_context()
On Tue, Mar 20, 2018 at 12:18:45AM +, Chris Wilson wrote: > As a complement to inject_preempt_context(), follow up with the function > to handle its completion. This will be useful should we wish to extend > the duties of the preempt-context for execlists. > > Signed-off-by: Chris Wilson > Cc: Jeff McGee > Cc: Michał Winiarski > --- > drivers/gpu/drm/i915/intel_lrc.c | 22 -- > 1 file changed, 12 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_lrc.c > b/drivers/gpu/drm/i915/intel_lrc.c > index 53f1c009ed7b..0bfaeb56b8c7 100644 > --- a/drivers/gpu/drm/i915/intel_lrc.c > +++ b/drivers/gpu/drm/i915/intel_lrc.c > @@ -531,8 +531,17 @@ static void inject_preempt_context(struct > intel_engine_cs *engine) > if (execlists->ctrl_reg) > writel(EL_CTRL_LOAD, execlists->ctrl_reg); > > - execlists_clear_active(&engine->execlists, EXECLISTS_ACTIVE_HWACK); > - execlists_set_active(&engine->execlists, EXECLISTS_ACTIVE_PREEMPT); > + execlists_clear_active(execlists, EXECLISTS_ACTIVE_HWACK); > + execlists_set_active(execlists, EXECLISTS_ACTIVE_PREEMPT); > +} > + > +static void complete_preempt_context(struct intel_engine_execlists > *execlists) > +{ > + execlists_cancel_port_requests(execlists); > + execlists_unwind_incomplete_requests(execlists); > + > + GEM_BUG_ON(!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT)); > + execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT); > } > > static void execlists_dequeue(struct intel_engine_cs *engine) > @@ -939,14 +948,7 @@ static void execlists_submission_tasklet(unsigned long > data) > if (status & GEN8_CTX_STATUS_COMPLETE && > buf[2*head + 1] == > execlists->preempt_complete_status) { > GEM_TRACE("%s preempt-idle\n", engine->name); > - > - execlists_cancel_port_requests(execlists); > - execlists_unwind_incomplete_requests(execlists); > - > - GEM_BUG_ON(!execlists_is_active(execlists, > - > EXECLISTS_ACTIVE_PREEMPT)); > - execlists_clear_active(execlists, > - > EXECLISTS_ACTIVE_PREEMPT); > + complete_preempt_context(execlists); > continue; > } > > -- > 2.16.2 > Reviewed-by: Jeff McGee ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 5/5] drm/i915/execlists: Flush pending preemption events during reset
On Tue, Mar 20, 2018 at 05:17:34PM -0700, Jeff McGee wrote: > On Tue, Mar 20, 2018 at 12:18:48AM +, Chris Wilson wrote: > > Catch up with the inflight CSB events, after disabling the tasklet > > before deciding which request was truly guilty of hanging the GPU. > > > > Signed-off-by: Chris Wilson > > Cc: Michał Winiarski > > CC: Michel Thierry > > Cc: Jeff McGee > > --- > > drivers/gpu/drm/i915/intel_lrc.c | 355 > > ++- > > 1 file changed, 197 insertions(+), 158 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/intel_lrc.c > > b/drivers/gpu/drm/i915/intel_lrc.c > > index e5a3ffbc273a..beb81f13a3cc 100644 > > --- a/drivers/gpu/drm/i915/intel_lrc.c > > +++ b/drivers/gpu/drm/i915/intel_lrc.c > > @@ -828,186 +828,192 @@ static void execlists_cancel_requests(struct > > intel_engine_cs *engine) > > local_irq_restore(flags); > > } > > > > -/* > > - * Check the unread Context Status Buffers and manage the submission of new > > - * contexts to the ELSP accordingly. > > - */ > > -static void execlists_submission_tasklet(unsigned long data) > > +static void process_csb(struct intel_engine_cs *engine) > > { > > - struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; > > struct intel_engine_execlists * const execlists = &engine->execlists; > > struct execlist_port * const port = execlists->port; > > - struct drm_i915_private *dev_priv = engine->i915; > > + struct drm_i915_private *i915 = engine->i915; > > + unsigned int head, tail; > > + const u32 *buf; > > bool fw = false; > > > > - /* We can skip acquiring intel_runtime_pm_get() here as it was taken > > -* on our behalf by the request (see i915_gem_mark_busy()) and it will > > -* not be relinquished until the device is idle (see > > -* i915_gem_idle_work_handler()). As a precaution, we make sure > > -* that all ELSP are drained i.e. we have processed the CSB, > > -* before allowing ourselves to idle and calling intel_runtime_pm_put(). > > -*/ > > - GEM_BUG_ON(!dev_priv->gt.awake); > > + if (unlikely(execlists->csb_use_mmio)) { > > + buf = (u32 * __force) > > + (i915->regs + > > i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); > > + execlists->csb_head = -1; /* force mmio read of CSB ptrs */ > > + } else { > > + /* The HWSP contains a (cacheable) mirror of the CSB */ > > + buf = &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; > > + } > > > > - /* Prefer doing test_and_clear_bit() as a two stage operation to avoid > > -* imposing the cost of a locked atomic transaction when submitting a > > -* new request (outside of the context-switch interrupt). > > + /* > > +* The write will be ordered by the uncached read (itself > > +* a memory barrier), so we do not need another in the form > > +* of a locked instruction. The race between the interrupt > > +* handler and the split test/clear is harmless as we order > > +* our clear before the CSB read. If the interrupt arrived > > +* first between the test and the clear, we read the updated > > +* CSB and clear the bit. If the interrupt arrives as we read > > +* the CSB or later (i.e. after we had cleared the bit) the bit > > +* is set and we do a new loop. > > */ > > - while (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) { > > - /* The HWSP contains a (cacheable) mirror of the CSB */ > > - const u32 *buf = > > - &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; > > - unsigned int head, tail; > > - > > - if (unlikely(execlists->csb_use_mmio)) { > > - buf = (u32 * __force) > > - (dev_priv->regs + > > i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); > > - execlists->csb_head = -1; /* force mmio read of CSB > > ptrs */ > > - } > > + __clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); > > + if (unlikely(execlists->csb_head == -1)) { /* following a reset */ > > + intel_uncore_forcewake_get(i915, execlists->fw_domains); > > + fw = true; > > + > > + head = readl(i915->regs + > > i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); > > +
Re: [Intel-gfx] [RFC 0/8] Force preemption
On Thu, Mar 22, 2018 at 09:28:00AM +, Chris Wilson wrote: > Quoting Tvrtko Ursulin (2018-03-22 09:22:55) > > > > On 21/03/2018 17:26, jeff.mc...@intel.com wrote: > > > From: Jeff McGee > > > > > > Force preemption uses engine reset to enforce a limit on the time > > > that a request targeted for preemption can block. This feature is > > > a requirement in automotive systems where the GPU may be shared by > > > clients of critically high priority and clients of low priority that > > > may not have been curated to be preemption friendly. There may be > > > more general applications of this feature. I'm sharing as an RFC to > > > stimulate that discussion and also to get any technical feedback > > > that I can before submitting to the product kernel that needs this. > > > I have developed the patches for ease of rebase, given that this is > > > for the moment considered a non-upstreamable feature. It would be > > > possible to refactor hangcheck to fully incorporate force preemption > > > as another tier of patience (or impatience) with the running request. > > > > Sorry if it was mentioned elsewhere and I missed it - but does this work > > only with stateless clients - or in other words, what would happen to > > stateful clients which would be force preempted? Or the answer is we > > don't care since they are misbehaving? > > They get notified of being guilty for causing a gpu reset; three strikes > and they are out (banned from using the gpu) using the current rules. > This is a very blunt hammer that requires the rest of the system to be > robust; one might argue time spent making the system robust would be > better served making sure that the timer never expired in the first place > thereby eliminating the need for a forced gpu reset. > -Chris Yes, for simplication the policy applied to force preempted contexts is the same as for hanging contexts. It is known that this feature should not be required in a fully curated system. It's a requirement if end user will be alllowed to install 3rd party apps to run in the non-critical domain. -Jeff ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC 6/8] drm/i915: Fix loop on CSB processing
On Wed, Mar 21, 2018 at 06:06:44PM +, Chris Wilson wrote: > Quoting Jeff McGee (2018-03-21 17:33:04) > > On Wed, Mar 21, 2018 at 10:26:23AM -0700, jeff.mc...@intel.com wrote: > > > From: Jeff McGee > > > > > > Signed-off-by: Jeff McGee > > > --- > > > drivers/gpu/drm/i915/intel_lrc.c | 2 +- > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > diff --git a/drivers/gpu/drm/i915/intel_lrc.c > > > b/drivers/gpu/drm/i915/intel_lrc.c > > > index beb81f13a3cc..cec4e1653daf 100644 > > > --- a/drivers/gpu/drm/i915/intel_lrc.c > > > +++ b/drivers/gpu/drm/i915/intel_lrc.c > > > @@ -1009,7 +1009,7 @@ static void execlists_submission_tasklet(unsigned > > > long data) > > >* imposing the cost of a locked atomic transaction when submitting > > > a > > >* new request (outside of the context-switch interrupt). > > >*/ > > > - if (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) > > > + while (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) > > Assuming that this accidentally went missing in the refactor. Chris? > > No. process_csb became a do{} while. The caller did a test_bit to avoid > the function call for normal rescheduling paths. > -Chris But there is no loop in process_csb(). -Jeff ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC 6/8] drm/i915: Fix loop on CSB processing
On Wed, Mar 21, 2018 at 10:26:23AM -0700, jeff.mc...@intel.com wrote: > From: Jeff McGee > > Signed-off-by: Jeff McGee > --- > drivers/gpu/drm/i915/intel_lrc.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/intel_lrc.c > b/drivers/gpu/drm/i915/intel_lrc.c > index beb81f13a3cc..cec4e1653daf 100644 > --- a/drivers/gpu/drm/i915/intel_lrc.c > +++ b/drivers/gpu/drm/i915/intel_lrc.c > @@ -1009,7 +1009,7 @@ static void execlists_submission_tasklet(unsigned long > data) >* imposing the cost of a locked atomic transaction when submitting a >* new request (outside of the context-switch interrupt). >*/ > - if (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) > + while (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) Assuming that this accidentally went missing in the refactor. Chris? > process_csb(engine); > > if (!execlists_is_active(&engine->execlists, EXECLISTS_ACTIVE_PREEMPT)) > -- > 2.16.2 > ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC 7/8] drm/i915: Skip CSB processing on invalid CSB tail
On Wed, Mar 21, 2018 at 10:26:24AM -0700, jeff.mc...@intel.com wrote: > From: Jeff McGee > > Engine reset is fast. A context switch interrupt may be generated just > prior to the reset such that the top half handler is racing with reset > post-processing. The handler may set the irq_posted bit again after > the reset code has cleared it to start fresh. Then the re-enabled > tasklet will read the CSB head and tail from MMIO, which will be at > the hardware reset values of 0 and 7 respectively, given that no > actual CSB event has occurred since the reset. Mayhem then ensues as > the tasklet starts processing invalid CSB entries. > > We can handle this corner case without adding any new synchronization > between the irq top half and the reset work item. The tasklet can > just skip CSB processing if the tail is not sane. > > Signed-off-by: Jeff McGee > --- If I drop this patch and substitute https://patchwork.freedesktop.org/patch/211831/ I will see irq_posted get set after reset which causes the first tasklet run to re-process a previous CSB event and hit GEM_BUG_ON that nothing was active. -Jeff ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 4/8] drm/i915: Split execlists/guc reset prepartions
From: Chris Wilson In the next patch, we will make the execlists reset prepare callback take into account preemption by flushing the context-switch handler. This is not applicable to the GuC submission backend, so split the two into their own backend callbacks. Signed-off-by: Chris Wilson Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee --- drivers/gpu/drm/i915/intel_guc_submission.c | 39 + drivers/gpu/drm/i915/intel_lrc.c| 11 +--- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c index 207cda062626..779c8d3156e5 100644 --- a/drivers/gpu/drm/i915/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/intel_guc_submission.c @@ -776,6 +776,44 @@ static void guc_submission_tasklet(unsigned long data) guc_dequeue(engine); } +static struct i915_request * +guc_reset_prepare(struct intel_engine_cs *engine) +{ + struct intel_engine_execlists * const execlists = &engine->execlists; + + /* +* Prevent request submission to the hardware until we have +* completed the reset in i915_gem_reset_finish(). If a request +* is completed by one engine, it may then queue a request +* to a second via its execlists->tasklet *just* as we are +* calling engine->init_hw() and also writing the ELSP. +* Turning off the execlists->tasklet until the reset is over +* prevents the race. +* +* Note that this needs to be a single atomic operation on the +* tasklet (flush existing tasks, prevent new tasks) to prevent +* a race between reset and set-wedged. It is not, so we do the best +* we can atm and make sure we don't lock the machine up in the more +* common case of recursively being called from set-wedged from inside +* i915_reset. +*/ + if (!atomic_read(&execlists->tasklet.count)) + tasklet_kill(&execlists->tasklet); + tasklet_disable(&execlists->tasklet); + + /* +* We're using worker to queue preemption requests from the tasklet in +* GuC submission mode. +* Even though tasklet was disabled, we may still have a worker queued. +* Let's make sure that all workers scheduled before disabling the +* tasklet are completed before continuing with the reset. +*/ + if (engine->i915->guc.preempt_wq) + flush_workqueue(engine->i915->guc.preempt_wq); + + return i915_gem_find_active_request(engine); +} + /* * Everything below here is concerned with setup & teardown, and is * therefore not part of the somewhat time-critical batch-submission @@ -1235,6 +1273,7 @@ int intel_guc_submission_enable(struct intel_guc *guc) &engine->execlists; execlists->tasklet.func = guc_submission_tasklet; + engine->reset.prepare = guc_reset_prepare; engine->park = guc_submission_park; engine->unpark = guc_submission_unpark; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index f662a9524233..e5a3ffbc273a 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1688,16 +1688,6 @@ execlists_reset_prepare(struct intel_engine_cs *engine) tasklet_kill(&execlists->tasklet); tasklet_disable(&execlists->tasklet); - /* -* We're using worker to queue preemption requests from the tasklet in -* GuC submission mode. -* Even though tasklet was disabled, we may still have a worker queued. -* Let's make sure that all workers scheduled before disabling the -* tasklet are completed before continuing with the reset. -*/ - if (engine->i915->guc.preempt_wq) - flush_workqueue(engine->i915->guc.preempt_wq); - return i915_gem_find_active_request(engine); } @@ -2115,6 +2105,7 @@ static void execlists_set_default_submission(struct intel_engine_cs *engine) engine->cancel_requests = execlists_cancel_requests; engine->schedule = execlists_schedule; engine->execlists.tasklet.func = execlists_submission_tasklet; + engine->reset.prepare = execlists_reset_prepare; engine->park = NULL; engine->unpark = NULL; -- 2.16.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 0/8] Force preemption
From: Jeff McGee Force preemption uses engine reset to enforce a limit on the time that a request targeted for preemption can block. This feature is a requirement in automotive systems where the GPU may be shared by clients of critically high priority and clients of low priority that may not have been curated to be preemption friendly. There may be more general applications of this feature. I'm sharing as an RFC to stimulate that discussion and also to get any technical feedback that I can before submitting to the product kernel that needs this. I have developed the patches for ease of rebase, given that this is for the moment considered a non-upstreamable feature. It would be possible to refactor hangcheck to fully incorporate force preemption as another tier of patience (or impatience) with the running request. Chris Wilson (5): drm/i915/execlists: Refactor out complete_preempt_context() drm/i915: Add control flags to i915_handle_error() drm/i915: Move engine reset prepare/finish to backends drm/i915: Split execlists/guc reset prepartions drm/i915/execlists: Flush pending preemption events during reset Jeff McGee (3): drm/i915: Fix loop on CSB processing drm/i915: Skip CSB processing on invalid CSB tail drm/i915: Force preemption to complete via engine reset drivers/gpu/drm/i915/i915_debugfs.c | 4 +- drivers/gpu/drm/i915/i915_drv.c | 17 +- drivers/gpu/drm/i915/i915_drv.h | 10 +- drivers/gpu/drm/i915/i915_gem.c | 69 ++-- drivers/gpu/drm/i915/i915_gpu_error.h| 3 + drivers/gpu/drm/i915/i915_irq.c | 55 +-- drivers/gpu/drm/i915/i915_params.c | 3 + drivers/gpu/drm/i915/i915_params.h | 1 + drivers/gpu/drm/i915/i915_request.c | 2 +- drivers/gpu/drm/i915/intel_engine_cs.c | 40 +++ drivers/gpu/drm/i915/intel_guc_submission.c | 39 ++ drivers/gpu/drm/i915/intel_hangcheck.c | 8 +- drivers/gpu/drm/i915/intel_lrc.c | 436 ++- drivers/gpu/drm/i915/intel_ringbuffer.c | 20 +- drivers/gpu/drm/i915/intel_ringbuffer.h | 13 +- drivers/gpu/drm/i915/selftests/intel_hangcheck.c | 13 +- 16 files changed, 469 insertions(+), 264 deletions(-) -- 2.16.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 8/8] drm/i915: Force preemption to complete via engine reset
From: Jeff McGee The hardware can complete the requested preemption at only certain points in execution. Thus an uncooperative request that avoids those points can block a preemption indefinitely. Our only option to bound the preemption latency is to trigger reset and recovery just as we would if a request had hung the hardware. This is so-called forced preemption. This change adds that capability as an option for systems with extremely strict scheduling latency requirements for its high priority requests. This option must be used with great care. The force-preempted requests will be discarded at the point of reset, resulting in various degrees of disruption to the owning application up to and including crash. The option is enabled by specifying a non-zero value for new i915 module parameter fpreempt_timeout. This value becomes the time in milliseconds after initiation of preemption at which the reset is triggered if the preemption has not completed normally. GuC mode is not supported. The fpreempt_timeout parameter is simply ignored. Signed-off-by: Jeff McGee Cc: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 27 -- drivers/gpu/drm/i915/i915_params.c | 3 +++ drivers/gpu/drm/i915/i915_params.h | 1 + drivers/gpu/drm/i915/intel_engine_cs.c | 40 + drivers/gpu/drm/i915/intel_lrc.c| 13 +++ drivers/gpu/drm/i915/intel_ringbuffer.h | 4 6 files changed, 86 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 38f7160d99c9..0ad448792bfb 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2896,8 +2896,24 @@ i915_gem_find_active_request(struct intel_engine_cs *engine) return active; } -static bool engine_stalled(struct intel_engine_cs *engine) +static bool engine_stalled(struct intel_engine_cs *engine, + struct i915_request *request) { + if (engine->fpreempt_stalled) { + /* Pardon the request if it managed to yield the +* engine by completing just prior to the reset. We +* could be even more sophisticated here and pardon +* the request if it preempted out (mid-batch) prior +* to the reset, but that's not so straight-forward +* to detect. Perhaps not worth splitting hairs when +* the request had clearly behaved badly to get here. +*/ + if (i915_request_completed(request)) + return false; + + return true; + } + if (!engine->hangcheck.stalled) return false; @@ -3038,7 +3054,7 @@ i915_gem_reset_request(struct intel_engine_cs *engine, * subsequent hangs. */ - if (engine_stalled(engine)) { + if (engine_stalled(engine, request)) { i915_gem_context_mark_guilty(request->ctx); skip_request(request); @@ -3046,6 +3062,13 @@ i915_gem_reset_request(struct intel_engine_cs *engine, if (i915_gem_context_is_banned(request->ctx)) engine_skip_context(request); } else { + /* If the request that we just pardoned was the target of a +* force preemption there is no possibility of the next +* request in line having started. +*/ + if (engine->fpreempt_stalled) + return NULL; + /* * Since this is not the hung engine, it may have advanced * since the hang declaration. Double check by refinding diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 08108ce5be21..71bc8213acb2 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -178,6 +178,9 @@ i915_param_named(enable_dpcd_backlight, bool, 0600, i915_param_named(enable_gvt, bool, 0400, "Enable support for Intel GVT-g graphics virtualization host support(default:false)"); +i915_param_named(fpreempt_timeout, uint, 0600, + "Wait time in msecs before forcing a preemption with reset (0:never force [default])"); + static __always_inline void _print_param(struct drm_printer *p, const char *name, const char *type, diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index c96360398072..1d50f223b637 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -55,6 +55,7 @@ struct drm_printer; param(int, edp_vswing, 0) \ param(int, reset, 2) \ param(unsigned int, inject_load_failure, 0) \ + param(unsigned int, fpreempt_timeout, 0) \ /* leave bools at the end to not create hole
[Intel-gfx] [RFC 2/8] drm/i915: Add control flags to i915_handle_error()
From: Chris Wilson Not all callers want the GPU error to handled in the same way, so expose a control parameter. In the first instance, some callers do not want the heavyweight error capture so add a bit to request the state to be captured and saved. v2: Pass msg down to i915_reset/i915_reset_engine so that we include the reason for the reset in the dev_notice(), superseding the earlier option to not print that notice. v3: Stash the reason inside the i915->gpu_error to handover to the direct reset from the blocking waiter. Signed-off-by: Chris Wilson Cc: Jeff McGee Cc: Mika Kuoppala Cc: Michel Thierry --- drivers/gpu/drm/i915/i915_debugfs.c | 4 +- drivers/gpu/drm/i915/i915_drv.c | 17 drivers/gpu/drm/i915/i915_drv.h | 10 ++--- drivers/gpu/drm/i915/i915_gpu_error.h| 3 ++ drivers/gpu/drm/i915/i915_irq.c | 55 ++-- drivers/gpu/drm/i915/i915_request.c | 2 +- drivers/gpu/drm/i915/intel_hangcheck.c | 8 ++-- drivers/gpu/drm/i915/selftests/intel_hangcheck.c | 13 +++--- 8 files changed, 60 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 964ea1a12357..7816cd53100a 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4011,8 +4011,8 @@ i915_wedged_set(void *data, u64 val) engine->hangcheck.stalled = true; } - i915_handle_error(i915, val, "Manually set wedged engine mask = %llx", - val); + i915_handle_error(i915, val, I915_ERROR_CAPTURE, + "Manually set wedged engine mask = %llx", val); wait_on_bit(&i915->gpu_error.flags, I915_RESET_HANDOFF, diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 1021bf40e236..6b04cc3be513 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1869,7 +1869,6 @@ static int i915_resume_switcheroo(struct drm_device *dev) /** * i915_reset - reset chip after a hang * @i915: #drm_i915_private to reset - * @flags: Instructions * * Reset the chip. Useful if a hang is detected. Marks the device as wedged * on failure. @@ -1884,7 +1883,7 @@ static int i915_resume_switcheroo(struct drm_device *dev) * - re-init interrupt state * - re-init display */ -void i915_reset(struct drm_i915_private *i915, unsigned int flags) +void i915_reset(struct drm_i915_private *i915) { struct i915_gpu_error *error = &i915->gpu_error; int ret; @@ -1901,8 +1900,9 @@ void i915_reset(struct drm_i915_private *i915, unsigned int flags) if (!i915_gem_unset_wedged(i915)) goto wakeup; - if (!(flags & I915_RESET_QUIET)) - dev_notice(i915->drm.dev, "Resetting chip after gpu hang\n"); + if (error->reason) + dev_notice(i915->drm.dev, + "Resetting chip for %s\n", error->reason); error->reset_count++; disable_irq(i915->drm.irq); @@ -2003,7 +2003,7 @@ static inline int intel_gt_reset_engine(struct drm_i915_private *dev_priv, /** * i915_reset_engine - reset GPU engine to recover from a hang * @engine: engine to reset - * @flags: options + * @msg: reason for GPU reset; or NULL for no dev_notice() * * Reset a specific GPU engine. Useful if a hang is detected. * Returns zero on successful reset or otherwise an error code. @@ -2013,7 +2013,7 @@ static inline int intel_gt_reset_engine(struct drm_i915_private *dev_priv, * - reset engine (which will force the engine to idle) * - re-init/configure engine */ -int i915_reset_engine(struct intel_engine_cs *engine, unsigned int flags) +int i915_reset_engine(struct intel_engine_cs *engine, const char *msg) { struct i915_gpu_error *error = &engine->i915->gpu_error; struct i915_request *active_request; @@ -2028,10 +2028,9 @@ int i915_reset_engine(struct intel_engine_cs *engine, unsigned int flags) goto out; } - if (!(flags & I915_RESET_QUIET)) { + if (msg) dev_notice(engine->i915->drm.dev, - "Resetting %s after gpu hang\n", engine->name); - } + "Resetting %s for %s\n", engine->name, msg); error->reset_engine_count[engine->id]++; if (!engine->i915->guc.execbuf_client) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e27ba8fb64e6..c9c3b2ba6a86 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2700,10 +2700,8 @@ extern void i915_driver_unload(struct drm_device *dev); extern int intel_gpu_reset(struct drm_i915_private *dev_priv, u32 engine_m
[Intel-gfx] [RFC 1/8] drm/i915/execlists: Refactor out complete_preempt_context()
From: Chris Wilson As a complement to inject_preempt_context(), follow up with the function to handle its completion. This will be useful should we wish to extend the duties of the preempt-context for execlists. Signed-off-by: Chris Wilson Cc: Jeff McGee Cc: Michał Winiarski --- drivers/gpu/drm/i915/intel_lrc.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 53f1c009ed7b..0bfaeb56b8c7 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -531,8 +531,17 @@ static void inject_preempt_context(struct intel_engine_cs *engine) if (execlists->ctrl_reg) writel(EL_CTRL_LOAD, execlists->ctrl_reg); - execlists_clear_active(&engine->execlists, EXECLISTS_ACTIVE_HWACK); - execlists_set_active(&engine->execlists, EXECLISTS_ACTIVE_PREEMPT); + execlists_clear_active(execlists, EXECLISTS_ACTIVE_HWACK); + execlists_set_active(execlists, EXECLISTS_ACTIVE_PREEMPT); +} + +static void complete_preempt_context(struct intel_engine_execlists *execlists) +{ + execlists_cancel_port_requests(execlists); + execlists_unwind_incomplete_requests(execlists); + + GEM_BUG_ON(!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT)); + execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT); } static void execlists_dequeue(struct intel_engine_cs *engine) @@ -939,14 +948,7 @@ static void execlists_submission_tasklet(unsigned long data) if (status & GEN8_CTX_STATUS_COMPLETE && buf[2*head + 1] == execlists->preempt_complete_status) { GEM_TRACE("%s preempt-idle\n", engine->name); - - execlists_cancel_port_requests(execlists); - execlists_unwind_incomplete_requests(execlists); - - GEM_BUG_ON(!execlists_is_active(execlists, - EXECLISTS_ACTIVE_PREEMPT)); - execlists_clear_active(execlists, - EXECLISTS_ACTIVE_PREEMPT); + complete_preempt_context(execlists); continue; } -- 2.16.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 5/8] drm/i915/execlists: Flush pending preemption events during reset
From: Chris Wilson Catch up with the inflight CSB events, after disabling the tasklet before deciding which request was truly guilty of hanging the GPU. Signed-off-by: Chris Wilson Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee --- drivers/gpu/drm/i915/intel_lrc.c | 355 ++- 1 file changed, 197 insertions(+), 158 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index e5a3ffbc273a..beb81f13a3cc 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -828,186 +828,192 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) local_irq_restore(flags); } -/* - * Check the unread Context Status Buffers and manage the submission of new - * contexts to the ELSP accordingly. - */ -static void execlists_submission_tasklet(unsigned long data) +static void process_csb(struct intel_engine_cs *engine) { - struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; struct intel_engine_execlists * const execlists = &engine->execlists; struct execlist_port * const port = execlists->port; - struct drm_i915_private *dev_priv = engine->i915; + struct drm_i915_private *i915 = engine->i915; + unsigned int head, tail; + const u32 *buf; bool fw = false; - /* We can skip acquiring intel_runtime_pm_get() here as it was taken -* on our behalf by the request (see i915_gem_mark_busy()) and it will -* not be relinquished until the device is idle (see -* i915_gem_idle_work_handler()). As a precaution, we make sure -* that all ELSP are drained i.e. we have processed the CSB, -* before allowing ourselves to idle and calling intel_runtime_pm_put(). -*/ - GEM_BUG_ON(!dev_priv->gt.awake); + if (unlikely(execlists->csb_use_mmio)) { + buf = (u32 * __force) + (i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); + execlists->csb_head = -1; /* force mmio read of CSB ptrs */ + } else { + /* The HWSP contains a (cacheable) mirror of the CSB */ + buf = &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; + } - /* Prefer doing test_and_clear_bit() as a two stage operation to avoid -* imposing the cost of a locked atomic transaction when submitting a -* new request (outside of the context-switch interrupt). + /* +* The write will be ordered by the uncached read (itself +* a memory barrier), so we do not need another in the form +* of a locked instruction. The race between the interrupt +* handler and the split test/clear is harmless as we order +* our clear before the CSB read. If the interrupt arrived +* first between the test and the clear, we read the updated +* CSB and clear the bit. If the interrupt arrives as we read +* the CSB or later (i.e. after we had cleared the bit) the bit +* is set and we do a new loop. */ - while (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) { - /* The HWSP contains a (cacheable) mirror of the CSB */ - const u32 *buf = - &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; - unsigned int head, tail; - - if (unlikely(execlists->csb_use_mmio)) { - buf = (u32 * __force) - (dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); - execlists->csb_head = -1; /* force mmio read of CSB ptrs */ - } + __clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); + if (unlikely(execlists->csb_head == -1)) { /* following a reset */ + intel_uncore_forcewake_get(i915, execlists->fw_domains); + fw = true; + + head = readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); + tail = GEN8_CSB_WRITE_PTR(head); + head = GEN8_CSB_READ_PTR(head); + execlists->csb_head = head; + } else { + const int write_idx = + intel_hws_csb_write_index(i915) - + I915_HWS_CSB_BUF0_INDEX; + + head = execlists->csb_head; + tail = READ_ONCE(buf[write_idx]); + } + GEM_TRACE("%s cs-irq head=%d [%d%s], tail=%d [%d%s]\n", + engine->name, + head, GEN8_CSB_READ_PTR(readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine, fw ? "" : "?", + tail, GEN8_CSB_WRITE_PTR(readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine, fw ? &
[Intel-gfx] [RFC 7/8] drm/i915: Skip CSB processing on invalid CSB tail
From: Jeff McGee Engine reset is fast. A context switch interrupt may be generated just prior to the reset such that the top half handler is racing with reset post-processing. The handler may set the irq_posted bit again after the reset code has cleared it to start fresh. Then the re-enabled tasklet will read the CSB head and tail from MMIO, which will be at the hardware reset values of 0 and 7 respectively, given that no actual CSB event has occurred since the reset. Mayhem then ensues as the tasklet starts processing invalid CSB entries. We can handle this corner case without adding any new synchronization between the irq top half and the reset work item. The tasklet can just skip CSB processing if the tail is not sane. Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/intel_lrc.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index cec4e1653daf..d420c2ecb50a 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -865,6 +865,14 @@ static void process_csb(struct intel_engine_cs *engine) head = readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); tail = GEN8_CSB_WRITE_PTR(head); head = GEN8_CSB_READ_PTR(head); + + /* The MMIO read CSB tail may be at the reset value of +* 0x7 if there hasn't been a valid CSB event since +* the engine reset. +*/ + if (tail >= GEN8_CSB_ENTRIES) + goto out; + execlists->csb_head = head; } else { const int write_idx = @@ -873,6 +881,7 @@ static void process_csb(struct intel_engine_cs *engine) head = execlists->csb_head; tail = READ_ONCE(buf[write_idx]); + GEM_BUG_ON(tail >= GEN8_CSB_ENTRIES); } GEM_TRACE("%s cs-irq head=%d [%d%s], tail=%d [%d%s]\n", engine->name, @@ -981,7 +990,7 @@ static void process_csb(struct intel_engine_cs *engine) writel(_MASKED_FIELD(GEN8_CSB_READ_PTR_MASK, head << 8), i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); } - +out: if (unlikely(fw)) intel_uncore_forcewake_put(i915, execlists->fw_domains); } -- 2.16.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 6/8] drm/i915: Fix loop on CSB processing
From: Jeff McGee Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/intel_lrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index beb81f13a3cc..cec4e1653daf 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1009,7 +1009,7 @@ static void execlists_submission_tasklet(unsigned long data) * imposing the cost of a locked atomic transaction when submitting a * new request (outside of the context-switch interrupt). */ - if (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) + while (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) process_csb(engine); if (!execlists_is_active(&engine->execlists, EXECLISTS_ACTIVE_PREEMPT)) -- 2.16.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 3/8] drm/i915: Move engine reset prepare/finish to backends
From: Chris Wilson In preparation to more carefully handling incomplete preemption during reset by execlists, we move the existing code wholesale to the backends under a couple of new reset vfuncs. Signed-off-by: Chris Wilson Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee --- drivers/gpu/drm/i915/i915_gem.c | 42 -- drivers/gpu/drm/i915/intel_lrc.c| 52 +++-- drivers/gpu/drm/i915/intel_ringbuffer.c | 20 +++-- drivers/gpu/drm/i915/intel_ringbuffer.h | 9 -- 4 files changed, 78 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 802df8e1a544..38f7160d99c9 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2917,7 +2917,7 @@ static bool engine_stalled(struct intel_engine_cs *engine) struct i915_request * i915_gem_reset_prepare_engine(struct intel_engine_cs *engine) { - struct i915_request *request = NULL; + struct i915_request *request; /* * During the reset sequence, we must prevent the engine from @@ -2940,40 +2940,7 @@ i915_gem_reset_prepare_engine(struct intel_engine_cs *engine) */ kthread_park(engine->breadcrumbs.signaler); - /* -* Prevent request submission to the hardware until we have -* completed the reset in i915_gem_reset_finish(). If a request -* is completed by one engine, it may then queue a request -* to a second via its execlists->tasklet *just* as we are -* calling engine->init_hw() and also writing the ELSP. -* Turning off the execlists->tasklet until the reset is over -* prevents the race. -* -* Note that this needs to be a single atomic operation on the -* tasklet (flush existing tasks, prevent new tasks) to prevent -* a race between reset and set-wedged. It is not, so we do the best -* we can atm and make sure we don't lock the machine up in the more -* common case of recursively being called from set-wedged from inside -* i915_reset. -*/ - if (!atomic_read(&engine->execlists.tasklet.count)) - tasklet_kill(&engine->execlists.tasklet); - tasklet_disable(&engine->execlists.tasklet); - - /* -* We're using worker to queue preemption requests from the tasklet in -* GuC submission mode. -* Even though tasklet was disabled, we may still have a worker queued. -* Let's make sure that all workers scheduled before disabling the -* tasklet are completed before continuing with the reset. -*/ - if (engine->i915->guc.preempt_wq) - flush_workqueue(engine->i915->guc.preempt_wq); - - if (engine->irq_seqno_barrier) - engine->irq_seqno_barrier(engine); - - request = i915_gem_find_active_request(engine); + request = engine->reset.prepare(engine); if (request && request->fence.error == -EIO) request = ERR_PTR(-EIO); /* Previous reset failed! */ @@ -3120,7 +3087,7 @@ void i915_gem_reset_engine(struct intel_engine_cs *engine, } /* Setup the CS to resume from the breadcrumb of the hung request */ - engine->reset_hw(engine, request); + engine->reset.reset(engine, request); } void i915_gem_reset(struct drm_i915_private *dev_priv) @@ -3172,7 +3139,8 @@ void i915_gem_reset(struct drm_i915_private *dev_priv) void i915_gem_reset_finish_engine(struct intel_engine_cs *engine) { - tasklet_enable(&engine->execlists.tasklet); + engine->reset.finish(engine); + kthread_unpark(engine->breadcrumbs.signaler); intel_uncore_forcewake_put(engine->i915, FORCEWAKE_ALL); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 0bfaeb56b8c7..f662a9524233 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1663,6 +1663,44 @@ static int gen9_init_render_ring(struct intel_engine_cs *engine) return init_workarounds_ring(engine); } +static struct i915_request * +execlists_reset_prepare(struct intel_engine_cs *engine) +{ + struct intel_engine_execlists * const execlists = &engine->execlists; + + /* +* Prevent request submission to the hardware until we have +* completed the reset in i915_gem_reset_finish(). If a request +* is completed by one engine, it may then queue a request +* to a second via its execlists->tasklet *just* as we are +* calling engine->init_hw() and also writing the ELSP. +* Turning off the execlists->tasklet until the reset is over +* prevents the race. +* +* Note that this needs to be a single atomic operation on the +* tasklet (flush exis
Re: [Intel-gfx] [PATCH] drm/i915: Flush pending interrupt following a GPU reset
On Wed, Mar 21, 2018 at 04:42:32PM +, Chris Wilson wrote: > Quoting Jeff McGee (2018-03-21 15:55:16) > > On Wed, Mar 21, 2018 at 03:00:23PM +, Chris Wilson wrote: > > > After resetting the GPU (or subset of engines), call synchronize_irq() > > > to flush any pending irq before proceeding with the cleanup. For a > > > device level reset, we disable the interupts around the reset, but when > > > resetting just one engine, we have to avoid such global disabling. This > > > leaves us open to an interrupt arriving for the engine as we try to > > > reset it. We already do try to flush the IIR following the reset, but we > > > have to ensure that the in-flight interrupt does not land after we start > > > cleaning up after the reset; enter synchronize_irq(). > > > > > > As it current stands, we very rarely, but fatally, see sequences such as: > > > > > > 2 57964564us : execlists_reset_prepare: rcs0 > > > 2 57964613us : execlists_reset: rcs0 seqno=424 > > > 0d.h1 57964615us : gen8_cs_irq_handler: rcs0 CS active=1 > > > 2d..1 57964617us : __i915_request_unsubmit: rcs0 fence 29:1056 <- > > > global_seqno 1060 > > > 2 57964703us : execlists_reset_finish: rcs0 > > > 0..s. 57964705us : execlists_submission_tasklet: rcs0 awake?=1, > > > active=0, irq-posted?=1 > > > > > I can repro this sequence easily with force preemption IGT. > > With the sequence I suggested? > -Chris Yes. Your approach to protecting port[1] context is working well. This is the only issue I'm still hitting. I'll post my updated RFC set in a sec. -Jeff ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Flush pending interrupt following a GPU reset
On Wed, Mar 21, 2018 at 03:00:23PM +, Chris Wilson wrote: > After resetting the GPU (or subset of engines), call synchronize_irq() > to flush any pending irq before proceeding with the cleanup. For a > device level reset, we disable the interupts around the reset, but when > resetting just one engine, we have to avoid such global disabling. This > leaves us open to an interrupt arriving for the engine as we try to > reset it. We already do try to flush the IIR following the reset, but we > have to ensure that the in-flight interrupt does not land after we start > cleaning up after the reset; enter synchronize_irq(). > > As it current stands, we very rarely, but fatally, see sequences such as: > > 2 57964564us : execlists_reset_prepare: rcs0 > 2 57964613us : execlists_reset: rcs0 seqno=424 > 0d.h1 57964615us : gen8_cs_irq_handler: rcs0 CS active=1 > 2d..1 57964617us : __i915_request_unsubmit: rcs0 fence 29:1056 <- > global_seqno 1060 > 2 57964703us : execlists_reset_finish: rcs0 > 0..s. 57964705us : execlists_submission_tasklet: rcs0 awake?=1, active=0, > irq-posted?=1 > I can repro this sequence easily with force preemption IGT. Just tried this patch and the issue is still there. For the moment I can just mitigate with https://patchwork.freedesktop.org/patch/211086/ > Signed-off-by: Chris Wilson > Cc: Mika Kuoppala > Cc: Michel Thierry > Cc: Michał Winiarski > --- > drivers/gpu/drm/i915/intel_uncore.c | 5 - > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/intel_uncore.c > b/drivers/gpu/drm/i915/intel_uncore.c > index 4c616d074a97..04830d6125d6 100644 > --- a/drivers/gpu/drm/i915/intel_uncore.c > +++ b/drivers/gpu/drm/i915/intel_uncore.c > @@ -2116,11 +2116,14 @@ int intel_gpu_reset(struct drm_i915_private > *dev_priv, unsigned engine_mask) > i915_stop_engines(dev_priv, engine_mask); > > ret = -ENODEV; > - if (reset) > + if (reset) { > + GEM_TRACE("engine_mask=%x\n", engine_mask); > ret = reset(dev_priv, engine_mask); > + } > if (ret != -ETIMEDOUT) > break; > > + synchronize_irq(dev_priv->drm.irq); > cond_resched(); > } > intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); > -- > 2.16.2 > > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 5/5] drm/i915/execlists: Flush pending preemption events during reset
On Tue, Mar 20, 2018 at 12:18:48AM +, Chris Wilson wrote: > Catch up with the inflight CSB events, after disabling the tasklet > before deciding which request was truly guilty of hanging the GPU. > > Signed-off-by: Chris Wilson > Cc: Michał Winiarski > CC: Michel Thierry > Cc: Jeff McGee > --- > drivers/gpu/drm/i915/intel_lrc.c | 355 > ++- > 1 file changed, 197 insertions(+), 158 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_lrc.c > b/drivers/gpu/drm/i915/intel_lrc.c > index e5a3ffbc273a..beb81f13a3cc 100644 > --- a/drivers/gpu/drm/i915/intel_lrc.c > +++ b/drivers/gpu/drm/i915/intel_lrc.c > @@ -828,186 +828,192 @@ static void execlists_cancel_requests(struct > intel_engine_cs *engine) > local_irq_restore(flags); > } > > -/* > - * Check the unread Context Status Buffers and manage the submission of new > - * contexts to the ELSP accordingly. > - */ > -static void execlists_submission_tasklet(unsigned long data) > +static void process_csb(struct intel_engine_cs *engine) > { > - struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; > struct intel_engine_execlists * const execlists = &engine->execlists; > struct execlist_port * const port = execlists->port; > - struct drm_i915_private *dev_priv = engine->i915; > + struct drm_i915_private *i915 = engine->i915; > + unsigned int head, tail; > + const u32 *buf; > bool fw = false; > > - /* We can skip acquiring intel_runtime_pm_get() here as it was taken > - * on our behalf by the request (see i915_gem_mark_busy()) and it will > - * not be relinquished until the device is idle (see > - * i915_gem_idle_work_handler()). As a precaution, we make sure > - * that all ELSP are drained i.e. we have processed the CSB, > - * before allowing ourselves to idle and calling intel_runtime_pm_put(). > - */ > - GEM_BUG_ON(!dev_priv->gt.awake); > + if (unlikely(execlists->csb_use_mmio)) { > + buf = (u32 * __force) > + (i915->regs + > i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); > + execlists->csb_head = -1; /* force mmio read of CSB ptrs */ > + } else { > + /* The HWSP contains a (cacheable) mirror of the CSB */ > + buf = &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; > + } > > - /* Prefer doing test_and_clear_bit() as a two stage operation to avoid > - * imposing the cost of a locked atomic transaction when submitting a > - * new request (outside of the context-switch interrupt). > + /* > + * The write will be ordered by the uncached read (itself > + * a memory barrier), so we do not need another in the form > + * of a locked instruction. The race between the interrupt > + * handler and the split test/clear is harmless as we order > + * our clear before the CSB read. If the interrupt arrived > + * first between the test and the clear, we read the updated > + * CSB and clear the bit. If the interrupt arrives as we read > + * the CSB or later (i.e. after we had cleared the bit) the bit > + * is set and we do a new loop. >*/ > - while (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) { > - /* The HWSP contains a (cacheable) mirror of the CSB */ > - const u32 *buf = > - &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; > - unsigned int head, tail; > - > - if (unlikely(execlists->csb_use_mmio)) { > - buf = (u32 * __force) > - (dev_priv->regs + > i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); > - execlists->csb_head = -1; /* force mmio read of CSB > ptrs */ > - } > + __clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); > + if (unlikely(execlists->csb_head == -1)) { /* following a reset */ > + intel_uncore_forcewake_get(i915, execlists->fw_domains); > + fw = true; > + > + head = readl(i915->regs + > i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); > + tail = GEN8_CSB_WRITE_PTR(head); > + head = GEN8_CSB_READ_PTR(head); > + execlists->csb_head = head; > + } else { > + const int write_idx = > + intel_hws_csb_write_index(i915) - > + I915_HWS_CSB_BUF0_INDEX; > + > + head = execlists->csb_head; > + tail = READ_ONCE(buf
[Intel-gfx] [RFC 4/8] drm/i915: Add a wait_for routine with more exact timeout
From: Jeff McGee The current non-atomic wait_for routines convert the provided usec timeout into jiffies with upward rounding. This can increase the actual timeout several msecs which is fine in most cases. In the next patch we need the timeout to conform more exactly to what is requested. This patch is required to support the force preemption feature. Change-Id: I20372ccd4db6609c42a6b41000ca7ff7700358fc Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/intel_drv.h | 22 ++ 1 file changed, 22 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index fa800918f67d..7cb6619129c3 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -75,6 +75,28 @@ (Wmax)) #define wait_for(COND, MS) _wait_for((COND), (MS) * 1000, 10, 1000) +#define _wait_for_exact(COND, US, Wmin, Wmax) ({ \ + u64 timeout__ = local_clock() + (US) * 1000;\ + long wait__ = (Wmin); /* recommended min for usleep is 10 us */ \ + int ret__; \ + might_sleep(); \ + for (;;) { \ + bool expired__ = (local_clock() > timeout__); \ + if (COND) { \ + ret__ = 0; \ + break; \ + } \ + if (expired__) {\ + ret__ = -ETIMEDOUT; \ + break; \ + } \ + usleep_range(wait__, wait__ * 2); \ + if (wait__ < (Wmax))\ + wait__ <<= 1; \ + } \ + ret__; \ +}) + /* If CONFIG_PREEMPT_COUNT is disabled, in_atomic() always reports false. */ #if defined(CONFIG_DRM_I915_DEBUG) && defined(CONFIG_PREEMPT_COUNT) # define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) WARN_ON_ONCE((ATOMIC) && !in_atomic()) -- 2.16.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 7/8] drm/i915: Allow reset without error capture
From: Jeff McGee Pull the reset handling out of i915_handle_error() so that it can be called by that function and directly by the upcoming force preemption handler. This allows the force preemption handler to bypass the error capture that i915_handle_error() does before getting on with the reset. We do not want error capture for force preemption because it adds significant latency (~10 msecs measured on APL). This patch is required to support the force preemption feature. Change-Id: I41b4fae1adc197f0e70cec47cb960a0d7fa55f48 Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_irq.c | 75 +++-- 2 files changed, 45 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d8524357373e..ade09f97be5c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3245,6 +3245,8 @@ __printf(3, 4) void i915_handle_error(struct drm_i915_private *dev_priv, u32 engine_mask, const char *fmt, ...); +void i915_handle_reset(struct drm_i915_private *dev_priv, + u32 engine_mask); extern void intel_irq_init(struct drm_i915_private *dev_priv); extern void intel_irq_fini(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a34f459f8ac1..ab5d4d40083d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2673,41 +2673,17 @@ static void i915_clear_error_registers(struct drm_i915_private *dev_priv) } /** - * i915_handle_error - handle a gpu error + * i915_handle_reset - handle a gpu reset * @dev_priv: i915 device private - * @engine_mask: mask representing engines that are hung - * @fmt: Error message format string + * @engine_mask: mask representing engines that require reset * - * Do some basic checking of register state at error time and - * dump it to the syslog. Also call i915_capture_error_state() to make - * sure we get a record and make it available in debugfs. Fire a uevent - * so userspace knows something bad happened (should trigger collection - * of a ring dump etc.). + * Executes reset on the given engines. */ -void i915_handle_error(struct drm_i915_private *dev_priv, - u32 engine_mask, - const char *fmt, ...) +void i915_handle_reset(struct drm_i915_private *dev_priv, + u32 engine_mask) { struct intel_engine_cs *engine; unsigned int tmp; - va_list args; - char error_msg[80]; - - va_start(args, fmt); - vscnprintf(error_msg, sizeof(error_msg), fmt, args); - va_end(args); - - /* -* In most cases it's guaranteed that we get here with an RPM -* reference held, for example because there is a pending GPU -* request that won't finish until the reset is done. This -* isn't the case at least when we get here by doing a -* simulated reset via debugfs, so get an RPM reference. -*/ - intel_runtime_pm_get(dev_priv); - - i915_capture_error_state(dev_priv, engine_mask, error_msg); - i915_clear_error_registers(dev_priv); /* * Try engine reset when available. We fall back to full reset if @@ -2731,14 +2707,14 @@ void i915_handle_error(struct drm_i915_private *dev_priv, } if (!engine_mask) - goto out; + return; /* Full reset needs the mutex, stop any other user trying to do so. */ if (test_and_set_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags)) { wait_event(dev_priv->gpu_error.reset_queue, !test_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags)); - goto out; + return; } /* Prevent any other reset-engine attempt. */ @@ -2759,8 +2735,43 @@ void i915_handle_error(struct drm_i915_private *dev_priv, clear_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags); wake_up_all(&dev_priv->gpu_error.reset_queue); +} +/** + * i915_handle_error - handle a gpu error + * @dev_priv: i915 device private + * @engine_mask: mask representing engines that are hung + * @fmt: Error message format string + * + * Do some basic checking of register state at error time and + * dump it to the syslog. Also call i915_capture_error_state() to make + * sure we get a record and make it available in debugfs. Fire a uevent + * so userspace knows something bad happened (should trigger collection + * of a ring dump etc.). + */ +void i915_handle_error(struct drm_i915_private *dev_priv, + u32 engine_mask, + const char *fmt, ...) +{ + va_list args; + char error_msg[80]; + + va_start(args, fmt); + vscn
[Intel-gfx] [RFC 0/8] Force preemption
From: Jeff McGee Force preemption uses engine reset to enforce a limit on the time that a request targeted for preemption can block. This feature is a requirement in automotive systems where the GPU may be shared by clients of critically high priority and clients of low priority that may not have been curated to be preemption friendly. There may be more general applications of this feature. I'm sharing as an RFC to stimulate that discussion and also to get any technical feedback that I can before submitting to the product kernel that needs this. I have developed the patches for ease of rebase, given that this is for the moment considered a non-upstreamable feature. It would be possible to refactor hangcheck to fully incorporate force preemption as another tier of patience (or impatience) with the running request. Jeff McGee (8): drm/i915: Downgrade tasklet GEM_BUG_ON for request not completed drm/i915: Skip CSB processing on invalid CSB tail drm/i915: Execlists to mark the HWSP upon preemption finished drm/i915: Add a wait_for routine with more exact timeout drm/i915: Consider preemption when finding the active request drm/i915: Repair the preemption context if hit by reset drm/i915: Allow reset without error capture drm/i915: Force preemption to complete via engine reset drivers/gpu/drm/i915/i915_drv.c | 14 +- drivers/gpu/drm/i915/i915_drv.h | 4 ++ drivers/gpu/drm/i915/i915_gem.c | 86 ++--- drivers/gpu/drm/i915/i915_irq.c | 75 drivers/gpu/drm/i915/i915_params.c | 3 ++ drivers/gpu/drm/i915/i915_params.h | 1 + drivers/gpu/drm/i915/intel_drv.h| 22 + drivers/gpu/drm/i915/intel_engine_cs.c | 53 drivers/gpu/drm/i915/intel_lrc.c| 81 +-- drivers/gpu/drm/i915/intel_ringbuffer.h | 20 +++- 10 files changed, 314 insertions(+), 45 deletions(-) -- 2.16.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 2/8] drm/i915: Skip CSB processing on invalid CSB tail
From: Jeff McGee Engine reset is fast. A context switch interrupt may be generated just prior to the reset such that the top half handler is racing with reset post-processing. The handler may set the irq_posted bit again after the reset code has cleared it to start fresh. Then the re-enabled tasklet will read the CSB head and tail from MMIO, which will be at the hardware reset values of 0 and 7 respectively, given that no actual CSB event has occurred since the reset. Mayhem then ensues as the tasklet starts processing invalid CSB entries. We can handle this corner case without adding any new synchronization between the irq top half and the reset work item. The tasklet can just skip CSB processing if the tail is not sane. This patch is required to support the force preemption feature. Test: Run IGT gem_exec_fpreempt repeatedly. Change-Id: Ic7eb00600480bd62331c397dd92b747d946241e4 Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/intel_lrc.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 7d93fcd56d34..5f63d1d6a2d6 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -851,6 +851,14 @@ static void intel_lrc_irq_handler(unsigned long data) head = readl(dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); tail = GEN8_CSB_WRITE_PTR(head); head = GEN8_CSB_READ_PTR(head); + + /* The MMIO read CSB tail may be at the reset value of +* 0x7 if there hasn't been a valid CSB event since +* the engine reset. Skip on to dequeue if so. +*/ + if (tail >= GEN8_CSB_ENTRIES) + break; + execlists->csb_head = head; } else { const int write_idx = @@ -859,6 +867,7 @@ static void intel_lrc_irq_handler(unsigned long data) head = execlists->csb_head; tail = READ_ONCE(buf[write_idx]); + GEM_BUG_ON(tail >= GEN8_CSB_ENTRIES); } while (head != tail) { -- 2.16.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 1/8] drm/i915: Downgrade tasklet GEM_BUG_ON for request not completed
From: Jeff McGee It is possible for the hardware to be reset just as a context is completing. The reset post-processing may see the seqno update and assume that the context escaped corruption, but the context may have been disrupted in the save out process. The corruption may screw up the HEAD and TAIL pointers such that the next submission of the context switches out without running the intended request. The GEM_BUG_ON will be hit in this situation, but it is not really a driver error. So make it a GEM_WARN_ON so that we notice while letting hangcheck detect and clean up. This patch is required to support the force preemption feature. Test: Run IGT gem_exec_fpreempt repeatedly with CONFIG_DRM_I915_DEBUG_GEM. Change-Id: I87da4b16bad805fe48153a9ed9169900681ebba7 Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/intel_lrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index b44861459d24..7d93fcd56d34 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -920,7 +920,7 @@ static void intel_lrc_irq_handler(unsigned long data) GEM_BUG_ON(count == 0); if (--count == 0) { GEM_BUG_ON(status & GEN8_CTX_STATUS_PREEMPTED); - GEM_BUG_ON(!i915_gem_request_completed(rq)); + GEM_WARN_ON(!i915_gem_request_completed(rq)); execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT); trace_i915_gem_request_out(rq); -- 2.16.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 5/8] drm/i915: Consider preemption when finding the active request
From: Jeff McGee The active request is found by scanning the engine timeline for the request that follows the last completed request. That method is accurate if there is no preemption in progress, because the engine will certainly have started that request. If there is a preemption in progress, it could have completed leaving the engine idle. In this case the request we identified with the above method is not active and may not even have been started. We must check for this condition to avoid fingering an innocent request during reset. This patch is required to support the force preemption feature. Test: Run IGT gem_exec_fpreempt repeatedly. Change-Id: I63a9f64446e24d4ee36b4af32854699bda006ddd Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/i915_gem.c | 49 + 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e2961e3913b8..9780d9026ce6 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2739,9 +2739,9 @@ static void i915_gem_context_mark_innocent(struct i915_gem_context *ctx) } struct drm_i915_gem_request * -i915_gem_find_active_request(struct intel_engine_cs *engine) +i915_gem_find_pending_request(struct intel_engine_cs *engine) { - struct drm_i915_gem_request *request, *active = NULL; + struct drm_i915_gem_request *request, *pending = NULL; unsigned long flags; /* We are called by the error capture and reset at a random @@ -2762,12 +2762,53 @@ i915_gem_find_active_request(struct intel_engine_cs *engine) GEM_BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &request->fence.flags)); - active = request; + pending = request; break; } spin_unlock_irqrestore(&engine->timeline->lock, flags); - return active; + return pending; +} + +struct drm_i915_gem_request * +i915_gem_find_active_request(struct intel_engine_cs *engine) +{ + struct intel_engine_execlists * const execlists = &engine->execlists; + struct drm_i915_gem_request *request; + + /* The pending request is active if no preemption is in progress */ + if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT)) + return i915_gem_find_pending_request(engine); + + /* Preemption has finished. Engine idle. */ + if (intel_engine_preempt_finished(engine)) + return NULL; + + request = i915_gem_find_pending_request(engine); + + /* Preemption has flushed all requests off the engine. Engine idle. */ + if (!request) + return NULL; + + /* The pending request likely is active and blocking the in-progress +* preemption. But there is a race in our previous checks. The request +* that was actually blocking preemption could have completed (a batch- +* boundary preemption) such that the engine is idle and the pending +* request we have identified was the next in line. We must wait for +* at least as long as it would take for the preempt-to-idle context +* to mark the preemption done to verify this. We use 500 usecs to +* account for a worst case delay from the seqno write of the +* completing request and the preempt finished write. +*/ + if (!_wait_for_exact(intel_engine_preempt_finished(engine), 500, 10, 50)) + return NULL; + + /* +* We didn't see the preemption done after a sufficient wait. Thus the +* pending request we sampled above was in fact active and blocking +* the preemption. +*/ + return request; } static bool engine_stalled(struct intel_engine_cs *engine) -- 2.16.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 8/8] drm/i915: Force preemption to complete via engine reset
From: Jeff McGee The hardware can complete the requested preemption at only certain points in execution. Thus an uncooperative request that avoids those points can block a preemption indefinitely. Our only option to bound the preemption latency is to trigger reset and recovery just as we would if a request had hung the hardware. This is so-called forced preemption. This change adds that capability as an option for systems with extremely strict scheduling latency requirements for its high priority requests. This option must be used with great care. The force-preempted requests will be discarded at the point of reset, resulting in various degrees of disruption to the owning application up to and including crash. The option is enabled by specifying a non-zero value for new i915 module parameter fpreempt_timeout. This value becomes the time in milliseconds after initiation of preemption at which the reset is triggered if the preemption has not completed normally. Test: Run IGT gem_exec_fpreempt. Change-Id: Iafd3609012621c57fa9e490dfeeac46ae541b5c2 Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/i915_drv.c | 14 - drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 37 +-- drivers/gpu/drm/i915/i915_params.c | 3 ++ drivers/gpu/drm/i915/i915_params.h | 1 + drivers/gpu/drm/i915/intel_engine_cs.c | 53 + drivers/gpu/drm/i915/intel_lrc.c| 24 ++- drivers/gpu/drm/i915/intel_ringbuffer.h | 6 8 files changed, 136 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index b627370d5a9c..3f2394d61ea2 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -811,8 +811,16 @@ static int i915_workqueues_init(struct drm_i915_private *dev_priv) if (dev_priv->hotplug.dp_wq == NULL) goto out_free_wq; + if (INTEL_INFO(dev_priv)->has_logical_ring_preemption) { + dev_priv->fpreempt_wq = alloc_ordered_workqueue("i915-fpreempt", + WQ_HIGHPRI); + if (dev_priv->fpreempt_wq == NULL) + goto out_free_dp_wq; + } return 0; +out_free_dp_wq: + destroy_workqueue(dev_priv->hotplug.dp_wq); out_free_wq: destroy_workqueue(dev_priv->wq); out_err: @@ -832,6 +840,8 @@ static void i915_engines_cleanup(struct drm_i915_private *i915) static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv) { + if (INTEL_INFO(dev_priv)->has_logical_ring_preemption) + destroy_workqueue(dev_priv->fpreempt_wq); destroy_workqueue(dev_priv->hotplug.dp_wq); destroy_workqueue(dev_priv->wq); } @@ -2007,7 +2017,9 @@ int i915_reset_engine(struct intel_engine_cs *engine, unsigned int flags) if (!(flags & I915_RESET_QUIET)) { dev_notice(engine->i915->drm.dev, - "Resetting %s after gpu hang\n", engine->name); + "Resetting %s %s\n", engine->name, + engine->fpreempt_active ? + "for force preemption" : "after gpu hang"); } error->reset_engine_count[engine->id]++; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ade09f97be5c..514e640d8406 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2290,6 +2290,8 @@ struct drm_i915_private { */ struct workqueue_struct *wq; + struct workqueue_struct *fpreempt_wq; + /* Display functions */ struct drm_i915_display_funcs display; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 9780d9026ce6..d556743c578a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2811,9 +2811,21 @@ i915_gem_find_active_request(struct intel_engine_cs *engine) return request; } -static bool engine_stalled(struct intel_engine_cs *engine) +static bool engine_stalled(struct intel_engine_cs *engine, + struct drm_i915_gem_request *request) { if (!intel_vgpu_active(engine->i915)) { + if (engine->fpreempt_active) { + /* Pardon the request if it managed to complete or +* preempt prior to the reset. +*/ + if (i915_gem_request_completed(request) || + intel_engine_preempt_finished(engine)) + return false; + + return true; + } + if (!engine->hangcheck.stalled) return false; @@ -2858,6 +2870,13 @@
[Intel-gfx] [RFC 3/8] drm/i915: Execlists to mark the HWSP upon preemption finished
From: Jeff McGee In the next patch we are improving how we find the active request on an engine with a pending preemption. We need to know if the preemption has completed or not. This determination can be made most robustly by having the preemption context write a preemption finished indicator to the hardware status page. This patch is required to support the force preemption feature. Change-Id: I4123283aec02e21d13c7cb55f329cf3f553b5d2c Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/intel_lrc.c| 27 --- drivers/gpu/drm/i915/intel_ringbuffer.h | 14 +- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 5f63d1d6a2d6..b2f838c484b0 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -512,19 +512,37 @@ static void port_assign(struct execlist_port *port, port_set(port, port_pack(i915_gem_request_get(rq), port_count(port))); } +#define PREEMPT_BREADCRUMB_DWORDS 0x8 static void inject_preempt_context(struct intel_engine_cs *engine) { struct intel_context *ce = &engine->i915->preempt_context->engine[engine->id]; + u32 *cs = ce->ring->vaddr + ce->ring->tail; u32 __iomem *elsp = engine->i915->regs + i915_mmio_reg_offset(RING_ELSP(engine)); unsigned int n; GEM_BUG_ON(engine->i915->preempt_context->hw_id != PREEMPT_ID); - GEM_BUG_ON(!IS_ALIGNED(ce->ring->size, WA_TAIL_BYTES)); + GEM_BUG_ON(intel_engine_preempt_finished(engine)); - memset(ce->ring->vaddr + ce->ring->tail, 0, WA_TAIL_BYTES); - ce->ring->tail += WA_TAIL_BYTES; + if (engine->id == RCS) { + cs = gen8_emit_ggtt_write_rcs(cs, I915_GEM_HWS_PREEMPT_FINISHED, + intel_hws_preempt_done_address(engine)); + } else { + cs = gen8_emit_ggtt_write(cs, I915_GEM_HWS_PREEMPT_FINISHED, + intel_hws_preempt_done_address(engine)); + *cs++ = MI_NOOP; + *cs++ = MI_NOOP; + } + *cs++ = MI_NOOP; + *cs++ = MI_NOOP; + + GEM_BUG_ON(!IS_ALIGNED(ce->ring->size, + PREEMPT_BREADCRUMB_DWORDS * sizeof(u32))); + GEM_BUG_ON((void *)cs - (ce->ring->vaddr + ce->ring->tail) != + PREEMPT_BREADCRUMB_DWORDS * sizeof(u32)); + + ce->ring->tail += PREEMPT_BREADCRUMB_DWORDS * sizeof(u32); ce->ring->tail &= (ce->ring->size - 1); ce->lrc_reg_state[CTX_RING_TAIL+1] = ce->ring->tail; @@ -911,6 +929,8 @@ static void intel_lrc_irq_handler(unsigned long data) EXECLISTS_ACTIVE_PREEMPT)); execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT); + GEM_BUG_ON(!intel_engine_preempt_finished(engine)); + intel_engine_clear_preempt(engine); continue; } @@ -1507,6 +1527,7 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine) execlists->csb_head = -1; execlists->active = 0; + intel_engine_clear_preempt(engine); /* After a GPU reset, we may have requests to replay */ if (!i915_modparams.enable_guc_submission && execlists->first) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 5b9117b3cba4..25eb23bc06eb 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -625,11 +625,12 @@ intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value) #define I915_GEM_HWS_INDEX_ADDR (I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT) #define I915_GEM_HWS_PREEMPT_INDEX 0x32 #define I915_GEM_HWS_PREEMPT_ADDR (I915_GEM_HWS_PREEMPT_INDEX << MI_STORE_DWORD_INDEX_SHIFT) +#define I915_GEM_HWS_PREEMPT_FINISHED 1 #define I915_GEM_HWS_PID_INDEX 0x40 #define I915_GEM_HWS_PID_ADDR (I915_GEM_HWS_PID_INDEX << MI_STORE_DWORD_INDEX_SHIFT) #define I915_GEM_HWS_CID_INDEX 0x48 #define I915_GEM_HWS_CID_ADDR (I915_GEM_HWS_CID_INDEX << MI_STORE_DWORD_INDEX_SHIFT) -#define I915_GEM_HWS_SCRATCH_INDEX 0x50 +#define I915_GEM_HWS_SCRATCH_INDEX 0x58 #define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT) #define I915_HWS_CSB_BUF0_INDEX0x10 @@ -749,6 +750,17 @@ static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine) return intel_read_status_page(engine, I915_GEM_HWS_INDEX); } +static inline bool intel_engine_preempt_finished(struct intel_engine_
[Intel-gfx] [RFC 6/8] drm/i915: Repair the preemption context if hit by reset
From: Jeff McGee It is possible for the preemption context to be active on an engine when the engine is reset. The preemption context is not tracked via the request mechanism, so the normal reset handling will not detect this scenario and will not be able to fixup possible context corruption. So add some extra logic to do this. This patch is required to support the force preemption feature. Test: Run IGT gem_exec_fpreempt repeatedly. Change-Id: Ifd0f17726111f3b702dd900064b7f375bbb42808 Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/intel_lrc.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index b2f838c484b0..581483886153 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1619,6 +1619,25 @@ static void reset_common_ring(struct intel_engine_cs *engine, spin_unlock_irqrestore(&engine->timeline->lock, flags); + /* If a preemption was pending when the reset occurred, and no +* active request was found when the reset completed, it is +* possible that the preemption context was hit by the reset. +* We must assume that the context is corrupted so repair it. +*/ + if (execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT) && + !request) { + struct i915_gem_context *ctx = engine->i915->preempt_context; + ce = &ctx->engine[engine->id]; + + execlists_init_reg_state(ce->lrc_reg_state, +ctx, engine, ce->ring); + ce->lrc_reg_state[CTX_RING_BUFFER_START+1] = + i915_ggtt_offset(ce->ring->vma); + ce->lrc_reg_state[CTX_RING_HEAD+1] = ce->ring->tail; + + return; + } + /* If the request was innocent, we leave the request in the ELSP * and will try to replay it on restarting. The context image may * have been corrupted by the reset, in which case we may have -- 2.16.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] ✓ Fi.CI.IGT: success for series starting with [CI,1/8] drm/i915: Define an engine class enum for the uABI
On Fri, Nov 10, 2017 at 06:14:17PM +, Chris Wilson wrote: > Quoting Patchwork (2017-11-10 16:46:14) > > == Series Details == > > > > Series: series starting with [CI,1/8] drm/i915: Define an engine class enum > > for the uABI > > URL : https://patchwork.freedesktop.org/series/33606/ > > State : success > > > > == Summary == > > > > Test kms_busy: > > Subgroup extended-modeset-hang-oldfb-with-reset-render-c: > > dmesg-warn -> PASS (shard-hsw) fdo#102249 > > > > fdo#102249 https://bugs.freedesktop.org/show_bug.cgi?id=102249 > > > > shard-hswtotal:2584 pass:1453 dwarn:1 dfail:2 fail:10 > > skip:1118 time:9370s > > Blacklisted hosts: > > shard-apltotal:2568 pass:1586 dwarn:3 dfail:1 fail:22 skip:955 > > time:12758s > > shard-kbltotal:2534 pass:1638 dwarn:31 dfail:4 fail:24 skip:835 > > time:9791s > > shard-snbtotal:2584 pass:1199 dwarn:2 dfail:2 fail:10 > > skip:1371 time:7769s > > > > == Logs == > > > > For more details see: > > https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7062/shards.html > > Sealed in the uabi, no regrets! > > Thanks everyone for the review, > -Chris Hi Chris. Should this series for context isolation be added to the 4.14 LTS? -Jeff ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/guc: Clear terminated attribute bit on GuC preemption context
From: Jeff McGee If GuC firmware performs an engine reset while that engine had a preemption pending, it will set the terminated attribute bit on our preemption stage descriptor. GuC firmware retains all pending work items for a high-priority GuC client, unlike the normal-priority GuC client where work items are dropped. It wants to make sure the preempt- to-idle work doesn't run when scheduling resumes, and uses this bit to inform its scheduler and presumably us as well. Our job is to clear it for the next preemption after reset, otherwise that and future preemptions will never complete. We'll just clear it every time. Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/i915_guc_submission.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 3049a0781b88..d14c1342f09d 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -590,6 +590,7 @@ static void inject_preempt_context(struct work_struct *work) struct intel_guc *guc = container_of(preempt_work, typeof(*guc), preempt_work[engine->id]); struct i915_guc_client *client = guc->preempt_client; + struct guc_stage_desc *stage_desc = __get_stage_desc(client); struct intel_ring *ring = client->owner->engine[engine->id].ring; u32 ctx_desc = lower_32_bits(intel_lr_context_descriptor(client->owner, engine)); @@ -623,6 +624,20 @@ static void inject_preempt_context(struct work_struct *work) ring->tail / sizeof(u64), 0); spin_unlock_irq(&client->wq_lock); + /* +* If GuC firmware performs an engine reset while that engine had +* a preemption pending, it will set the terminated attribute bit +* on our preemption stage descriptor. GuC firmware retains all +* pending work items for a high-priority GuC client, unlike the +* normal-priority GuC client where work items are dropped. It +* wants to make sure the preempt-to-idle work doesn't run when +* scheduling resumes, and uses this bit to inform its scheduler +* and presumably us as well. Our job is to clear it for the next +* preemption after reset, otherwise that and future preemptions +* will never complete. We'll just clear it every time. +*/ + stage_desc->attribute &= ~GUC_STAGE_DESC_ATTR_TERMINATED; + data[0] = INTEL_GUC_ACTION_REQUEST_PREEMPTION; data[1] = client->stage_id; data[2] = INTEL_GUC_PREEMPT_OPTION_DROP_WORK_Q | -- 2.14.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v6] drm/i915/guc: Add support for reset engine using GuC commands
On Wed, Nov 01, 2017 at 01:58:04PM +, Chris Wilson wrote: > Quoting Michel Thierry (2017-10-31 22:53:09) > > This patch adds per engine reset and recovery (TDR) support when GuC is > > used to submit workloads to GPU. > > > > In the case of i915 directly submission to ELSP, driver manages hang > > detection, recovery and resubmission. With GuC submission these tasks > > are shared between driver and GuC. i915 is still responsible for detecting > > a hang, and when it does it only requests GuC to reset that Engine. GuC > > internally manages acquiring forcewake and idling the engine before > > resetting it. > > > > Once the reset is successful, i915 takes over again and handles the > > resubmission. The scheduler in i915 knows which requests are pending so > > after resetting a engine, pending workloads/requests are resubmitted > > again. > > > > v2: s/i915_guc_request_engine_reset/i915_guc_reset_engine/ to match the > > non-guc function names. > > > > v3: Removed debug message about engine restarting from which request, > > since the new baseline do it regardless of submission mode. (Chris) > > > > v4: Rebase. > > > > v5: Do not pass unnecessary reporting flags to the fw (Jeff); > > tasklet_schedule(&execlists->irq_tasklet) handles the resubmit; rebase. > > > > v6: Rename the existing reset engine function and share a similar > > interface between guc and non-guc paths (Chris). > > > > Signed-off-by: Michel Thierry > > Cc: Chris Wilson > > --- > > drivers/gpu/drm/i915/i915_drv.c | 15 +-- > > drivers/gpu/drm/i915/i915_drv.h | 2 ++ > > drivers/gpu/drm/i915/intel_guc.c | 24 > > drivers/gpu/drm/i915/intel_guc_fwif.h | 1 + > > drivers/gpu/drm/i915/intel_uncore.c | 5 - > > 5 files changed, 40 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/i915_drv.c > > b/drivers/gpu/drm/i915/i915_drv.c > > index af745749509c..359333a423cf 100644 > > --- a/drivers/gpu/drm/i915/i915_drv.c > > +++ b/drivers/gpu/drm/i915/i915_drv.c > > @@ -1950,6 +1950,12 @@ void i915_reset(struct drm_i915_private *i915, > > unsigned int flags) > > goto finish; > > } > > > > +static inline int intel_gt_reset_engine(struct drm_i915_private *dev_priv, > > + struct intel_engine_cs *engine) > > +{ > > + return intel_gpu_reset(dev_priv, intel_engine_flag(engine)); > > +} > > + > > /** > > * i915_reset_engine - reset GPU engine to recover from a hang > > * @engine: engine to reset > > @@ -1984,10 +1990,15 @@ int i915_reset_engine(struct intel_engine_cs > > *engine, unsigned int flags) > > goto out; > > } > > > > - ret = intel_gpu_reset(engine->i915, intel_engine_flag(engine)); > > + if (!engine->i915->guc.execbuf_client) > > + ret = intel_gt_reset_engine(engine->i915, engine); > > + else > > + ret = intel_guc_reset_engine(&engine->i915->guc, engine); > > + > > if (ret) { > > /* If we fail here, we expect to fallback to a global reset > > */ > > - DRM_DEBUG_DRIVER("Failed to reset %s, ret=%d\n", > > + DRM_DEBUG_DRIVER("%sFailed to reset %s, ret=%d\n", > > +(engine->i915->guc.execbuf_client ? "GUC > > ":""), > > A bit overkill on the parentheses there ;) > > Lgtm, can you please ping, say, Jeff or Daniele for an r-b on the guc > interaction? > -Chris There is one small change needed in the GuC preemption protocol to make it compatible with GuC engine reset. I will send that shortly. There are also a couple of corner case bugs with engine reset in our current firmware versions. We are planning a firmware update to address those. But the host-side code here is fine. So... Reviewed-by: Jeff McGee ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Debugfs to disable context banning
On Wed, Oct 18, 2017 at 11:01:13AM +0200, Daniel Vetter wrote: > On Tue, Oct 17, 2017 at 09:23:43AM -0700, Jeff McGee wrote: > > On Tue, Oct 17, 2017 at 05:36:54PM +0200, Daniel Vetter wrote: > > > On Tue, Oct 17, 2017 at 08:25:33AM -0700, jeff.mc...@intel.com wrote: > > > > From: Jeff McGee > > > > > > > > Useful for stress testing various reset scenarios. The ioctl that we > > > > have for specific client/context banning disable is difficult to utilize > > > > outside of unit testing. > > > > > > Do we have these stress tests available somewhere? > > > -Daniel > > > > > Potentially any test scenario that relies upon app/umd instead of IGT to > > inject batches that need to be reset would benefit from the ability to > > disable context banning. We are using such scenarios to validate for the > > Yocto APL project, specifically for a feature where preemption of non- > > preemptible batches is forced using reset. It it not needed for IGT-based > > reset stress tests. > > Is that test suite public somewhere? > -Daniel No, but it could be. I don't own it. Anyway, I'll reintroduce this patch when I have a better case to make for it. It was worth a try ;) -Jeff ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2] drm/i915: Debugfs to disable context banning
From: Jeff McGee Useful for stress testing various reset scenarios. The ioctl that we have for specific client/context banning disable is difficult to utilize outside of unit testing. v2: Fix rebase compilation error Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/i915_debugfs.c | 27 ++- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 3 ++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 0bb6e01121fc..af14f019926d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4408,6 +4408,30 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_min_freq_fops, i915_min_freq_get, i915_min_freq_set, "%llu\n"); +static int i915_banning_disable_get(void *data, u64 *val) +{ + struct drm_device *dev = data; + struct drm_i915_private *dev_priv = dev->dev_private; + + *val = dev_priv->gpu_error.banning_disabled; + + return 0; +} + +static int i915_banning_disable_set(void *data, u64 val) +{ + struct drm_device *dev = data; + struct drm_i915_private *dev_priv = dev->dev_private; + + dev_priv->gpu_error.banning_disabled = (bool)val; + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(i915_banning_disable_fops, + i915_banning_disable_get, i915_banning_disable_set, + "%llu\n"); + static int i915_cache_sharing_get(void *data, u64 *val) { @@ -4828,7 +4852,8 @@ static const struct i915_debugfs_files { {"i915_dp_test_active", &i915_displayport_test_active_fops}, {"i915_guc_log_control", &i915_guc_log_control_fops}, {"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops}, - {"i915_ipc_status", &i915_ipc_status_fops} + {"i915_ipc_status", &i915_ipc_status_fops}, + {"i915_banning_disable", &i915_banning_disable_fops}, }; int i915_debugfs_register(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c7b2ca6aff05..da65b6f8cc6f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1667,6 +1667,8 @@ struct i915_gpu_error { /* For missed irq/seqno simulation. */ unsigned long test_irq_rings; + + bool banning_disabled; }; enum modeset_restore { diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 20fcac37c85a..e0cb53cafc66 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2770,7 +2770,8 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj, static bool ban_context(const struct i915_gem_context *ctx, unsigned int score) { - return (i915_gem_context_is_bannable(ctx) && + return (!ctx->i915->gpu_error.banning_disabled && + i915_gem_context_is_bannable(ctx) && score >= CONTEXT_SCORE_BAN_THRESHOLD); } -- 2.14.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Debugfs to disable context banning
On Tue, Oct 17, 2017 at 05:36:54PM +0200, Daniel Vetter wrote: > On Tue, Oct 17, 2017 at 08:25:33AM -0700, jeff.mc...@intel.com wrote: > > From: Jeff McGee > > > > Useful for stress testing various reset scenarios. The ioctl that we > > have for specific client/context banning disable is difficult to utilize > > outside of unit testing. > > Do we have these stress tests available somewhere? > -Daniel > Potentially any test scenario that relies upon app/umd instead of IGT to inject batches that need to be reset would benefit from the ability to disable context banning. We are using such scenarios to validate for the Yocto APL project, specifically for a feature where preemption of non- preemptible batches is forced using reset. It it not needed for IGT-based reset stress tests. -Jeff > > > > Signed-off-by: Jeff McGee > > --- > > drivers/gpu/drm/i915/i915_debugfs.c | 25 + > > drivers/gpu/drm/i915/i915_drv.h | 2 ++ > > drivers/gpu/drm/i915/i915_gem.c | 3 ++- > > 3 files changed, 29 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c > > b/drivers/gpu/drm/i915/i915_debugfs.c > > index 0bb6e01121fc..17e6b388b80c 100644 > > --- a/drivers/gpu/drm/i915/i915_debugfs.c > > +++ b/drivers/gpu/drm/i915/i915_debugfs.c > > @@ -4408,6 +4408,30 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_min_freq_fops, > > i915_min_freq_get, i915_min_freq_set, > > "%llu\n"); > > > > +static int i915_banning_disable_get(void *data, u64 *val) > > +{ > > + struct drm_device *dev = data; > > + struct drm_i915_private *dev_priv = dev->dev_private; > > + > > + *val = dev_priv->gpu_error.banning_disabled; > > + > > + return 0; > > +} > > + > > +static int i915_banning_disable_set(void *data, u64 val) > > +{ > > + struct drm_device *dev = data; > > + struct drm_i915_private *dev_priv = dev->dev_private; > > + > > + dev_priv->gpu_error.banning_disabled = (bool)val; > > + > > + return 0; > > +} > > + > > +DEFINE_SIMPLE_ATTRIBUTE(i915_banning_disable_fops, > > + i915_banning_disable_get, i915_banning_disable_set, > > + "%llu\n"); > > + > > static int > > i915_cache_sharing_get(void *data, u64 *val) > > { > > @@ -4829,6 +4853,7 @@ static const struct i915_debugfs_files { > > {"i915_guc_log_control", &i915_guc_log_control_fops}, > > {"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops}, > > {"i915_ipc_status", &i915_ipc_status_fops} > > + {"i915_banning_disable", &i915_banning_disable_fops}, > > }; > > > > int i915_debugfs_register(struct drm_i915_private *dev_priv) > > diff --git a/drivers/gpu/drm/i915/i915_drv.h > > b/drivers/gpu/drm/i915/i915_drv.h > > index c7b2ca6aff05..da65b6f8cc6f 100644 > > --- a/drivers/gpu/drm/i915/i915_drv.h > > +++ b/drivers/gpu/drm/i915/i915_drv.h > > @@ -1667,6 +1667,8 @@ struct i915_gpu_error { > > > > /* For missed irq/seqno simulation. */ > > unsigned long test_irq_rings; > > + > > + bool banning_disabled; > > }; > > > > enum modeset_restore { > > diff --git a/drivers/gpu/drm/i915/i915_gem.c > > b/drivers/gpu/drm/i915/i915_gem.c > > index 20fcac37c85a..e0cb53cafc66 100644 > > --- a/drivers/gpu/drm/i915/i915_gem.c > > +++ b/drivers/gpu/drm/i915/i915_gem.c > > @@ -2770,7 +2770,8 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object > > *obj, > > static bool ban_context(const struct i915_gem_context *ctx, > > unsigned int score) > > { > > - return (i915_gem_context_is_bannable(ctx) && > > + return (!ctx->i915->gpu_error.banning_disabled && > > + i915_gem_context_is_bannable(ctx) && > > score >= CONTEXT_SCORE_BAN_THRESHOLD); > > } > > > > -- > > 2.14.2 > > > > ___ > > Intel-gfx mailing list > > Intel-gfx@lists.freedesktop.org > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx > > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Debugfs to disable context banning
From: Jeff McGee Useful for stress testing various reset scenarios. The ioctl that we have for specific client/context banning disable is difficult to utilize outside of unit testing. Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/i915_debugfs.c | 25 + drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 3 ++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 0bb6e01121fc..17e6b388b80c 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4408,6 +4408,30 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_min_freq_fops, i915_min_freq_get, i915_min_freq_set, "%llu\n"); +static int i915_banning_disable_get(void *data, u64 *val) +{ + struct drm_device *dev = data; + struct drm_i915_private *dev_priv = dev->dev_private; + + *val = dev_priv->gpu_error.banning_disabled; + + return 0; +} + +static int i915_banning_disable_set(void *data, u64 val) +{ + struct drm_device *dev = data; + struct drm_i915_private *dev_priv = dev->dev_private; + + dev_priv->gpu_error.banning_disabled = (bool)val; + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(i915_banning_disable_fops, + i915_banning_disable_get, i915_banning_disable_set, + "%llu\n"); + static int i915_cache_sharing_get(void *data, u64 *val) { @@ -4829,6 +4853,7 @@ static const struct i915_debugfs_files { {"i915_guc_log_control", &i915_guc_log_control_fops}, {"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops}, {"i915_ipc_status", &i915_ipc_status_fops} + {"i915_banning_disable", &i915_banning_disable_fops}, }; int i915_debugfs_register(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c7b2ca6aff05..da65b6f8cc6f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1667,6 +1667,8 @@ struct i915_gpu_error { /* For missed irq/seqno simulation. */ unsigned long test_irq_rings; + + bool banning_disabled; }; enum modeset_restore { diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 20fcac37c85a..e0cb53cafc66 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2770,7 +2770,8 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj, static bool ban_context(const struct i915_gem_context *ctx, unsigned int score) { - return (i915_gem_context_is_bannable(ctx) && + return (!ctx->i915->gpu_error.banning_disabled && + i915_gem_context_is_bannable(ctx) && score >= CONTEXT_SCORE_BAN_THRESHOLD); } -- 2.14.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Add in-flight request details to intel_engine_dump()
On Sun, Oct 15, 2017 at 09:43:10PM +0100, Chris Wilson wrote: > In the intel_engine_cs dumper, we were showing the request details for > the request queue but not of those requests already passed to the hw > (just a summary of the seqno). If we show those details, we can then > eliminate the entirely redundant and forgotten debugfs/i915_gem_request > > Signed-off-by: Chris Wilson > Cc: Jeff McGee > Cc: Mika Kuoppala > --- Reviewed-by: Jeff McGee > drivers/gpu/drm/i915/i915_debugfs.c| 49 > -- > drivers/gpu/drm/i915/intel_engine_cs.c | 35 +--- > 2 files changed, 19 insertions(+), 65 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c > b/drivers/gpu/drm/i915/i915_debugfs.c > index 0bb6e01121fc..bb7261266773 100644 > --- a/drivers/gpu/drm/i915/i915_debugfs.c > +++ b/drivers/gpu/drm/i915/i915_debugfs.c > @@ -643,54 +643,6 @@ static int i915_gem_batch_pool_info(struct seq_file *m, > void *data) > return 0; > } > > -static void print_request(struct seq_file *m, > - struct drm_i915_gem_request *rq, > - const char *prefix) > -{ > - seq_printf(m, "%s%x [%x:%x] prio=%d @ %dms: %s\n", prefix, > -rq->global_seqno, rq->ctx->hw_id, rq->fence.seqno, > -rq->priotree.priority, > -jiffies_to_msecs(jiffies - rq->emitted_jiffies), > -rq->timeline->common->name); > -} > - > -static int i915_gem_request_info(struct seq_file *m, void *data) > -{ > - struct drm_i915_private *dev_priv = node_to_i915(m->private); > - struct drm_device *dev = &dev_priv->drm; > - struct drm_i915_gem_request *req; > - struct intel_engine_cs *engine; > - enum intel_engine_id id; > - int ret, any; > - > - ret = mutex_lock_interruptible(&dev->struct_mutex); > - if (ret) > - return ret; > - > - any = 0; > - for_each_engine(engine, dev_priv, id) { > - int count; > - > - count = 0; > - list_for_each_entry(req, &engine->timeline->requests, link) > - count++; > - if (count == 0) > - continue; > - > - seq_printf(m, "%s requests: %d\n", engine->name, count); > - list_for_each_entry(req, &engine->timeline->requests, link) > - print_request(m, req, ""); > - > - any++; > - } > - mutex_unlock(&dev->struct_mutex); > - > - if (any == 0) > - seq_puts(m, "No requests\n"); > - > - return 0; > -} > - > static void i915_ring_seqno_info(struct seq_file *m, >struct intel_engine_cs *engine) > { > @@ -4753,7 +4705,6 @@ static const struct drm_info_list i915_debugfs_list[] = > { > {"i915_gem_gtt", i915_gem_gtt_info, 0}, > {"i915_gem_pin_display", i915_gem_gtt_info, 0, (void *)1}, > {"i915_gem_stolen", i915_gem_stolen_list_info }, > - {"i915_gem_request", i915_gem_request_info, 0}, > {"i915_gem_seqno", i915_gem_seqno_info, 0}, > {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, > {"i915_gem_interrupt", i915_interrupt_info, 0}, > diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c > b/drivers/gpu/drm/i915/intel_engine_cs.c > index a59b2a30ff5a..52340b56d898 100644 > --- a/drivers/gpu/drm/i915/intel_engine_cs.c > +++ b/drivers/gpu/drm/i915/intel_engine_cs.c > @@ -1622,8 +1622,10 @@ static void print_request(struct drm_printer *m, > struct drm_i915_gem_request *rq, > const char *prefix) > { > - drm_printf(m, "%s%x [%x:%x] prio=%d @ %dms: %s\n", prefix, > -rq->global_seqno, rq->ctx->hw_id, rq->fence.seqno, > + drm_printf(m, "%s%x%s [%x:%x] prio=%d @ %dms: %s\n", prefix, > +rq->global_seqno, > +i915_gem_request_completed(rq) ? "!" : "", > +rq->ctx->hw_id, rq->fence.seqno, > rq->priotree.priority, > jiffies_to_msecs(jiffies - rq->emitted_jiffies), > rq->timeline->common->name); > @@ -1631,8 +1633,9 @@ static void print_request(struct drm_printer *m, > > void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *m) > { > - struct intel_breadcrumbs *b = &engine->breadcrumbs; > - struct i915_gpu
[Intel-gfx] [PATCH 1/2] drm/i915: Properly lock the engine timeline in debugfs i915_gem_request
From: Jeff McGee We are racing with updates to the timeline. This can cause an inconsistent snapshot to be dumped, or even worse a NULL pointer dereference. Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/i915_debugfs.c | 27 ++- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 0bb6e01121fc..135828fb1904 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -657,33 +657,26 @@ static void print_request(struct seq_file *m, static int i915_gem_request_info(struct seq_file *m, void *data) { struct drm_i915_private *dev_priv = node_to_i915(m->private); - struct drm_device *dev = &dev_priv->drm; struct drm_i915_gem_request *req; struct intel_engine_cs *engine; enum intel_engine_id id; - int ret, any; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; + int any = 0; - any = 0; for_each_engine(engine, dev_priv, id) { - int count; + int count = 0; - count = 0; + spin_lock_irq(&engine->timeline->lock); list_for_each_entry(req, &engine->timeline->requests, link) count++; - if (count == 0) - continue; - - seq_printf(m, "%s requests: %d\n", engine->name, count); - list_for_each_entry(req, &engine->timeline->requests, link) - print_request(m, req, ""); - any++; + if (count) { + seq_printf(m, "%s requests: %d\n", engine->name, count); + list_for_each_entry(req, &engine->timeline->requests, link) + print_request(m, req, ""); + any++; + } + spin_unlock_irq(&engine->timeline->lock); } - mutex_unlock(&dev->struct_mutex); if (any == 0) seq_puts(m, "No requests\n"); -- 2.14.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/2] drm/i915: Include current seqno in debugfs i915_gem_request
From: Jeff McGee Debugfs i915_gem_request lists the entire queue of requests on the engine timeline. This will include requests that are complete but not yet removed from the timeline. So let's include in this snapshot the current seqno to help separate completed from pending. Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/i915_debugfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 135828fb1904..36d21f3c31ee 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -670,7 +670,9 @@ static int i915_gem_request_info(struct seq_file *m, void *data) count++; if (count) { - seq_printf(m, "%s requests: %d\n", engine->name, count); + seq_printf(m, "%s: requests %d, current seqno %x\n", + engine->name, count, + intel_engine_get_seqno(engine)); list_for_each_entry(req, &engine->timeline->requests, link) print_request(m, req, ""); any++; -- 2.14.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 07/10] drm/i915: Add information needed to track engine preempt state
On Thu, Oct 05, 2017 at 11:20:02AM +0200, Michał Winiarski wrote: > We shouldn't inspect ELSP context status (or any other bits depending on > specific submission backend) when using GuC submission. > Let's use another piece of HWSP for preempt context, to write its bit of > information, meaning that preemption has finished, and hardware is now > idle. > > Cc: Chris Wilson > Cc: Jeff Mcgee > Cc: Michal Wajdeczko > Cc: Oscar Mateo > Signed-off-by: Michał Winiarski Reviewed-by: Jeff McGee ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 05/10] drm/i915/guc: Split guc_wq_item_append
On Thu, Oct 05, 2017 at 11:13:44AM +0200, Michał Winiarski wrote: > We're using a special preempt context for HW to preempt into. We don't > want to emit any requests there, but we still need to wrap this context > into a valid GuC work item. > Let's cleanup the functions operating on GuC work items. > We can extract guc_request_add - responsible for adding GuC work item and > ringing the doorbell, and guc_wq_item_append - used by the function > above, not tied to the concept of gem request. > > Cc: Chris Wilson > Cc: Jeff Mcgee > Cc: Michal Wajdeczko > Cc: Oscar Mateo > Signed-off-by: Michał Winiarski Reviewed-by: Jeff McGee ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 04/10] drm/i915/guc: Add a second client, to be used for preemption
On Thu, Oct 05, 2017 at 11:13:43AM +0200, Michał Winiarski wrote: > From: Dave Gordon > > This second client is created with priority KMD_HIGH, and marked > as preemptive. This will allow us to request preemption using GuC actions. > > Cc: Chris Wilson > Cc: Jeff Mcgee > Cc: Michal Wajdeczko > Cc: Oscar Mateo > Signed-off-by: Dave Gordon > Signed-off-by: Michał Winiarski > --- > drivers/gpu/drm/i915/i915_debugfs.c| 4 > drivers/gpu/drm/i915/i915_guc_submission.c | 32 > ++ > drivers/gpu/drm/i915/intel_uc.h| 1 + > 3 files changed, 33 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c > b/drivers/gpu/drm/i915/i915_debugfs.c > index b4a6ac60e7c6..1a963c13cab8 100644 > --- a/drivers/gpu/drm/i915/i915_debugfs.c > +++ b/drivers/gpu/drm/i915/i915_debugfs.c > @@ -2488,6 +2488,10 @@ static int i915_guc_info(struct seq_file *m, void > *data) > > seq_printf(m, "\nGuC execbuf client @ %p:\n", guc->execbuf_client); > i915_guc_client_info(m, dev_priv, guc->execbuf_client); > + if (guc->preempt_client) { > + seq_printf(m, "\nGuC preempt client\n"); > + i915_guc_client_info(m, dev_priv, guc->preempt_client); > + } > > i915_guc_log_info(m, dev_priv); > > diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c > b/drivers/gpu/drm/i915/i915_guc_submission.c > index 374501a67274..e8052e86426d 100644 > --- a/drivers/gpu/drm/i915/i915_guc_submission.c > +++ b/drivers/gpu/drm/i915/i915_guc_submission.c > @@ -331,6 +331,8 @@ static void guc_stage_desc_init(struct intel_guc *guc, > memset(desc, 0, sizeof(*desc)); > > desc->attribute = GUC_STAGE_DESC_ATTR_ACTIVE | > GUC_STAGE_DESC_ATTR_KERNEL; > + if (client->priority <= GUC_CLIENT_PRIORITY_HIGH) > + desc->attribute |= GUC_STAGE_DESC_ATTR_PREEMPT; > desc->stage_id = client->stage_id; > desc->priority = client->priority; > desc->db_id = client->doorbell_id; > @@ -1154,7 +1156,7 @@ int i915_guc_submission_enable(struct drm_i915_private > *dev_priv) >sizeof(struct guc_wq_item) * >I915_NUM_ENGINES > GUC_WQ_SIZE); > I think that client is still being initialized above to guc->execbuf_client. If so, can it be removed? > - if (!client) { > + if (!guc->execbuf_client) { > client = guc_client_alloc(dev_priv, > INTEL_INFO(dev_priv)->ring_mask, > GUC_CLIENT_PRIORITY_KMD_NORMAL, > @@ -1167,15 +1169,29 @@ int i915_guc_submission_enable(struct > drm_i915_private *dev_priv) > guc->execbuf_client = client; > } > > + if (!guc->preempt_client) { > + client = guc_client_alloc(dev_priv, > + INTEL_INFO(dev_priv)->ring_mask, > + GUC_CLIENT_PRIORITY_KMD_HIGH, > + dev_priv->preempt_context); > + if (IS_ERR(client)) { > + DRM_ERROR("Failed to create GuC client for > preemption!\n"); > + err = PTR_ERR(client); > + goto err_free_clients; > + } > + > + guc->preempt_client = client; > + } > + > err = intel_guc_sample_forcewake(guc); > if (err) > - goto err_execbuf_client; > + goto err_free_clients; > > guc_reset_wq(client); > > err = guc_init_doorbell_hw(guc); > if (err) > - goto err_execbuf_client; > + goto err_free_clients; > > /* Take over from manual control of ELSP (execlists) */ > guc_interrupts_capture(dev_priv); > @@ -1187,7 +1203,11 @@ int i915_guc_submission_enable(struct drm_i915_private > *dev_priv) > > return 0; > > -err_execbuf_client: > +err_free_clients: > + if (guc->preempt_client) { > + guc_client_free(guc->preempt_client); > + guc->preempt_client = NULL; > + } > guc_client_free(guc->execbuf_client); > guc->execbuf_client = NULL; > return err; > @@ -1202,6 +1222,10 @@ void i915_guc_submission_disable(struct > drm_i915_private *dev_priv) > /* Revert back to manual ELSP submission */ > intel_engines_reset_default_submission(dev_priv); > > + if (guc->preempt_client) { Do we need this check? It seems that execbuf_client and preempt_client are both required for GuC sub
Re: [Intel-gfx] [PATCH 03/10] drm/i915/guc: Add preemption action to GuC firmware interface
On Thu, Oct 05, 2017 at 11:13:42AM +0200, Michał Winiarski wrote: > We're using GuC action to request preemption. However, after requesting > preemption we need to wait for GuC to finish its own post-processing > before we start submitting our requests. Firmware is using shared > context to report its status. > Let's update GuC firmware interface with those new definitions. > > Cc: Jeff Mcgee > Cc: Michal Wajdeczko > Cc: Oscar Mateo > Signed-off-by: Michał Winiarski Reviewed-by: Jeff McGee ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Clear local engine-needs-reset bit if in progress elsewhere
On Wed, Sep 06, 2017 at 10:57:20PM +0100, Chris Wilson wrote: > Quoting Jeff McGee (2017-08-29 18:01:47) > > On Tue, Aug 29, 2017 at 04:17:46PM +0100, Chris Wilson wrote: > > > Quoting Jeff McGee (2017-08-29 16:04:17) > > > > On Tue, Aug 29, 2017 at 10:07:18AM +0100, Chris Wilson wrote: > > > > > Quoting Jeff McGee (2017-08-28 21:18:44) > > > > > > On Mon, Aug 28, 2017 at 08:44:48PM +0100, Chris Wilson wrote: > > > > > > > Quoting jeff.mc...@intel.com (2017-08-28 20:25:30) > > > > > > > > From: Jeff McGee > > > > > > > > > > > > > > > > If someone else is resetting the engine we should clear our own > > > > > > > > bit as > > > > > > > > part of skipping that engine. Otherwise we will later believe > > > > > > > > that it > > > > > > > > has not been reset successfully and then trigger full gpu > > > > > > > > reset. If the > > > > > > > > other guy's reset actually fails, he will trigger the full gpu > > > > > > > > reset. > > > > > > > > > > > > > > The reason we did continue on to the global reset was to serialise > > > > > > > i915_handle_error() with the other thread. Not a huge issue, but a > > > > > > > reasonable property to keep -- and we definitely want a to > > > > > > > explain why > > > > > > > only one reset at a time is important. > > > > > > > > > > > > > > bool intel_engine_lock_reset() { > > > > > > > if (!test_and_set_bit(I915_RESET_ENGINE + engine->id, > > > > > > > &engine->i915->gpu_error.flags)) > > > > > > > return true; > > > > > > > > > > > > > > intel_engine_wait_for_reset(engine); > > > > > > The current code doesn't wait for the other thread to finish the > > > > > > reset, but > > > > > > this would add that wait. > > > > > > > > > > Pardon? If we can't reset the engine, we go to the full reset which is > > > > > serialised, both with individual engine resets and other globals. > > > > > > > > > > > Did you intend that as an additional change to > > > > > > the current code? I don't think it is necessary. Each thread wants > > > > > > to > > > > > > reset some subset of engines, so it seems the thread can safely > > > > > > exit as soon > > > > > > as it knows each of those engines has been reset or is being reset > > > > > > as part > > > > > > of another thread that got the lock first. If any of the threads > > > > > > fail to > > > > > > reset an engine they "own", then full gpu reset is assured. > > > > > > > > > > It's unexpected for this function to return before the reset. > > > > > -Chris > > > > > > > > I'm a bit confused, so let's go back to the original code that I was > > > > trying > > > > to fix: > > > > > > > > > > > > /* > > > > * Try engine reset when available. We fall back to full reset > > > > if > > > > * single reset fails. > > > > */ > > > > if (intel_has_reset_engine(dev_priv)) { > > > > for_each_engine_masked(engine, dev_priv, engine_mask, > > > > tmp) { > > > > BUILD_BUG_ON(I915_RESET_MODESET >= > > > > I915_RESET_ENGINE); > > > > if (test_and_set_bit(I915_RESET_ENGINE + > > > > engine->id, > > > > > > > > &dev_priv->gpu_error.flags)) > > > > continue; > > > > > > > > if (i915_reset_engine(engine, 0) == 0) > > > > engine_mask &= > > > > ~intel_engine_flag(engine); > > > > > > > > clear_bit(I915_RESET_ENGINE + engine->id, > > > > &dev_priv->gp
Re: [Intel-gfx] [PATCH] drm/i915: Clear local engine-needs-reset bit if in progress elsewhere
On Tue, Aug 29, 2017 at 04:17:46PM +0100, Chris Wilson wrote: > Quoting Jeff McGee (2017-08-29 16:04:17) > > On Tue, Aug 29, 2017 at 10:07:18AM +0100, Chris Wilson wrote: > > > Quoting Jeff McGee (2017-08-28 21:18:44) > > > > On Mon, Aug 28, 2017 at 08:44:48PM +0100, Chris Wilson wrote: > > > > > Quoting jeff.mc...@intel.com (2017-08-28 20:25:30) > > > > > > From: Jeff McGee > > > > > > > > > > > > If someone else is resetting the engine we should clear our own bit > > > > > > as > > > > > > part of skipping that engine. Otherwise we will later believe that > > > > > > it > > > > > > has not been reset successfully and then trigger full gpu reset. If > > > > > > the > > > > > > other guy's reset actually fails, he will trigger the full gpu > > > > > > reset. > > > > > > > > > > The reason we did continue on to the global reset was to serialise > > > > > i915_handle_error() with the other thread. Not a huge issue, but a > > > > > reasonable property to keep -- and we definitely want a to explain why > > > > > only one reset at a time is important. > > > > > > > > > > bool intel_engine_lock_reset() { > > > > > if (!test_and_set_bit(I915_RESET_ENGINE + engine->id, > > > > > &engine->i915->gpu_error.flags)) > > > > > return true; > > > > > > > > > > intel_engine_wait_for_reset(engine); > > > > The current code doesn't wait for the other thread to finish the reset, > > > > but > > > > this would add that wait. > > > > > > Pardon? If we can't reset the engine, we go to the full reset which is > > > serialised, both with individual engine resets and other globals. > > > > > > > Did you intend that as an additional change to > > > > the current code? I don't think it is necessary. Each thread wants to > > > > reset some subset of engines, so it seems the thread can safely exit as > > > > soon > > > > as it knows each of those engines has been reset or is being reset as > > > > part > > > > of another thread that got the lock first. If any of the threads fail to > > > > reset an engine they "own", then full gpu reset is assured. > > > > > > It's unexpected for this function to return before the reset. > > > -Chris > > > > I'm a bit confused, so let's go back to the original code that I was trying > > to fix: > > > > > > /* > > * Try engine reset when available. We fall back to full reset if > > * single reset fails. > > */ > > if (intel_has_reset_engine(dev_priv)) { > > for_each_engine_masked(engine, dev_priv, engine_mask, tmp) { > > BUILD_BUG_ON(I915_RESET_MODESET >= > > I915_RESET_ENGINE); > > if (test_and_set_bit(I915_RESET_ENGINE + engine->id, > > &dev_priv->gpu_error.flags)) > > continue; > > > > if (i915_reset_engine(engine, 0) == 0) > > engine_mask &= ~intel_engine_flag(engine); > > > > clear_bit(I915_RESET_ENGINE + engine->id, > > &dev_priv->gpu_error.flags); > > wake_up_bit(&dev_priv->gpu_error.flags, > > I915_RESET_ENGINE + engine->id); > > } > > } > > > > if (!engine_mask) > > goto out; > > > > /* Full reset needs the mutex, stop any other user trying to do so. > > */ > > > > Let's say that 2 threads are here intending to reset render. #1 gets the > > lock > > and starts the render engine-only reset. #2 fails to get the lock which > > implies > > that someone else is in the process of resetting the render engine (with > > single > > engine reset or full gpu reset). #2 continues on without waiting but doesn't > > clear the render bit in engine_mask. So #2 will proceed to initiate a full > > gpu reset when it may not be necessary. That's the problem I was trying > > to
Re: [Intel-gfx] [PATCH] drm/i915: Clear local engine-needs-reset bit if in progress elsewhere
On Tue, Aug 29, 2017 at 10:07:18AM +0100, Chris Wilson wrote: > Quoting Jeff McGee (2017-08-28 21:18:44) > > On Mon, Aug 28, 2017 at 08:44:48PM +0100, Chris Wilson wrote: > > > Quoting jeff.mc...@intel.com (2017-08-28 20:25:30) > > > > From: Jeff McGee > > > > > > > > If someone else is resetting the engine we should clear our own bit as > > > > part of skipping that engine. Otherwise we will later believe that it > > > > has not been reset successfully and then trigger full gpu reset. If the > > > > other guy's reset actually fails, he will trigger the full gpu reset. > > > > > > The reason we did continue on to the global reset was to serialise > > > i915_handle_error() with the other thread. Not a huge issue, but a > > > reasonable property to keep -- and we definitely want a to explain why > > > only one reset at a time is important. > > > > > > bool intel_engine_lock_reset() { > > > if (!test_and_set_bit(I915_RESET_ENGINE + engine->id, > > > &engine->i915->gpu_error.flags)) > > > return true; > > > > > > intel_engine_wait_for_reset(engine); > > The current code doesn't wait for the other thread to finish the reset, but > > this would add that wait. > > Pardon? If we can't reset the engine, we go to the full reset which is > serialised, both with individual engine resets and other globals. > > > Did you intend that as an additional change to > > the current code? I don't think it is necessary. Each thread wants to > > reset some subset of engines, so it seems the thread can safely exit as soon > > as it knows each of those engines has been reset or is being reset as part > > of another thread that got the lock first. If any of the threads fail to > > reset an engine they "own", then full gpu reset is assured. > > It's unexpected for this function to return before the reset. > -Chris I'm a bit confused, so let's go back to the original code that I was trying to fix: /* * Try engine reset when available. We fall back to full reset if * single reset fails. */ if (intel_has_reset_engine(dev_priv)) { for_each_engine_masked(engine, dev_priv, engine_mask, tmp) { BUILD_BUG_ON(I915_RESET_MODESET >= I915_RESET_ENGINE); if (test_and_set_bit(I915_RESET_ENGINE + engine->id, &dev_priv->gpu_error.flags)) continue; if (i915_reset_engine(engine, 0) == 0) engine_mask &= ~intel_engine_flag(engine); clear_bit(I915_RESET_ENGINE + engine->id, &dev_priv->gpu_error.flags); wake_up_bit(&dev_priv->gpu_error.flags, I915_RESET_ENGINE + engine->id); } } if (!engine_mask) goto out; /* Full reset needs the mutex, stop any other user trying to do so. */ Let's say that 2 threads are here intending to reset render. #1 gets the lock and starts the render engine-only reset. #2 fails to get the lock which implies that someone else is in the process of resetting the render engine (with single engine reset or full gpu reset). #2 continues on without waiting but doesn't clear the render bit in engine_mask. So #2 will proceed to initiate a full gpu reset when it may not be necessary. That's the problem I was trying to address with my initial patch. Do you agree that #2 must clear this bit to avoid always triggering full gpu reset? If the engine-only reset done by #1 fails, #1 will do the fallback to full gpu reset, so there is no risk that we would miss the full gpu reset if it is really needed. Then there is the question of whether #2 should wait around for the render engine reset by #1 to complete. It doesn't in current code and I don't see why it needs to. But that can be a separate discussion from the above. -Jeff ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Clear local engine-needs-reset bit if in progress elsewhere
On Mon, Aug 28, 2017 at 08:44:48PM +0100, Chris Wilson wrote: > Quoting jeff.mc...@intel.com (2017-08-28 20:25:30) > > From: Jeff McGee > > > > If someone else is resetting the engine we should clear our own bit as > > part of skipping that engine. Otherwise we will later believe that it > > has not been reset successfully and then trigger full gpu reset. If the > > other guy's reset actually fails, he will trigger the full gpu reset. > > The reason we did continue on to the global reset was to serialise > i915_handle_error() with the other thread. Not a huge issue, but a > reasonable property to keep -- and we definitely want a to explain why > only one reset at a time is important. > > bool intel_engine_lock_reset() { > if (!test_and_set_bit(I915_RESET_ENGINE + engine->id, > &engine->i915->gpu_error.flags)) > return true; > > intel_engine_wait_for_reset(engine); The current code doesn't wait for the other thread to finish the reset, but this would add that wait. Did you intend that as an additional change to the current code? I don't think it is necessary. Each thread wants to reset some subset of engines, so it seems the thread can safely exit as soon as it knows each of those engines has been reset or is being reset as part of another thread that got the lock first. If any of the threads fail to reset an engine they "own", then full gpu reset is assured. -Jeff > return false; /* somebody else beat us to the reset */ > } > > void intel_engine_wait_for_reset() { > while (test_and_set_bit(I915_RESET_ENGINE + engine->id, > &engine->i915->gpu_error.flags)) > wait_on_bit(&engine->i915->gpu_error.flags, I915_RESET_ENGINE + > engine->id, > TASK_UNINTERRUPTIBLE); > } > > It can also be used by selftests/intel_hangcheck.c, so let's refactor > before we have 3 copies. > -Chris ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Clear local engine-needs-reset bit if in progress elsewhere
On Mon, Aug 28, 2017 at 12:41:58PM -0700, Michel Thierry wrote: > On 28/08/17 12:25, jeff.mc...@intel.com wrote: > >From: Jeff McGee > > > >If someone else is resetting the engine we should clear our own bit as > >part of skipping that engine. Otherwise we will later believe that it > >has not been reset successfully and then trigger full gpu reset. If the > >other guy's reset actually fails, he will trigger the full gpu reset. > > > > Did you hit this by manually setting wedged to 'x' ring repeatedly? > I haven't actually reproduced it. Have just been looking at the code a lot to try to develop reset for preemption enforcement. The implementation will call i915_handle_error from another work item that can run concurrent with hangcheck. > >Signed-off-by: Jeff McGee > >--- > > drivers/gpu/drm/i915/i915_irq.c | 4 +++- > > 1 file changed, 3 insertions(+), 1 deletion(-) > > > >diff --git a/drivers/gpu/drm/i915/i915_irq.c > >b/drivers/gpu/drm/i915/i915_irq.c > >index 5d391e689070..575d618ccdbf 100644 > >--- a/drivers/gpu/drm/i915/i915_irq.c > >+++ b/drivers/gpu/drm/i915/i915_irq.c > >@@ -2711,8 +2711,10 @@ void i915_handle_error(struct drm_i915_private > >*dev_priv, > > for_each_engine_masked(engine, dev_priv, engine_mask, tmp) { > > BUILD_BUG_ON(I915_RESET_MODESET >= I915_RESET_ENGINE); > > if (test_and_set_bit(I915_RESET_ENGINE + engine->id, > >- &dev_priv->gpu_error.flags)) > >+ &dev_priv->gpu_error.flags)) { > >+engine_mask &= ~intel_engine_flag(engine); > > continue; > >+} > > if (i915_reset_engine(engine, 0) == 0) > > engine_mask &= ~intel_engine_flag(engine); > > > > Reviewed-by: Michel Thierry ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Clear local engine-needs-reset bit if in progress elsewhere
From: Jeff McGee If someone else is resetting the engine we should clear our own bit as part of skipping that engine. Otherwise we will later believe that it has not been reset successfully and then trigger full gpu reset. If the other guy's reset actually fails, he will trigger the full gpu reset. Signed-off-by: Jeff McGee --- drivers/gpu/drm/i915/i915_irq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5d391e689070..575d618ccdbf 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2711,8 +2711,10 @@ void i915_handle_error(struct drm_i915_private *dev_priv, for_each_engine_masked(engine, dev_priv, engine_mask, tmp) { BUILD_BUG_ON(I915_RESET_MODESET >= I915_RESET_ENGINE); if (test_and_set_bit(I915_RESET_ENGINE + engine->id, -&dev_priv->gpu_error.flags)) +&dev_priv->gpu_error.flags)) { + engine_mask &= ~intel_engine_flag(engine); continue; + } if (i915_reset_engine(engine, 0) == 0) engine_mask &= ~intel_engine_flag(engine); -- 2.11.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [igt PATCH] igt/pm_rps: Remove remaining assert on CUR <= MAX
On Wed, Jun 21, 2017 at 12:55:42PM +0300, Arkadiusz Hiler wrote: > On Tue, Jun 20, 2017 at 06:15:52PM +0300, Arkadiusz Hiler wrote: > > On Tue, Jun 20, 2017 at 01:54:54PM +, Szwichtenberg, Radoslaw wrote: > > > On Wed, 2017-06-14 at 12:44 -0700, jeff.mc...@intel.com wrote: > > > > From: Jeff McGee > > > > > > > > This completes the change started by: > > > > > > > > commit 39cccab83b7c515a2b57abe679a8cb304c8933ef > > > > Author: Chris Wilson > > > > Date: Fri May 19 09:41:40 2017 +0100 > > > > > > > > igt/pm_rps: Allow CUR to be greater than MAX (overclocking) > > > > > > > > Cc: Chris Wilson > > > > Signed-off-by: Jeff McGee > > > Reviewed-by: Radoslaw Szwichtenberg > > > > Pushed. Thanks for the patch and the review. > > > > Excerpt from CONTRIBUTING: > > - > > Please use --subject-prefix="PATCH i-g-t" so that i-g-t patches are easily > > identified in the massive amount mails on intel-gfx. To ensure this is > > always > > done, autogen.sh will run: > > > > git config format.subjectprefix "PATCH i-g-t" > > > > on its first invocation. > > - > > > > Lack of proper prefix breaks filtering / patchwork and makes changes > > harder to track, and effectilvely it takes longer to get the patch in. > > > > The autogen.sh thing is a recent addition. > > Hey Jeff, > > The change has been reverted. > > At first the it looked like a sensible folloup to previous changes and > it even got r-bed, but as pointed out by Michal, this constraint still > should hold, as it's checked in a non-boost scenario. > > It hides bug introduced into the kernel by the commit: > "drm/i915: Define a separate variable and control for RPS waitboost frequency" > > for GuC submission path, as the check below always holds true as we have > waiters all the time: > if (client_boost || any_waiters) max = hw_max; > > What was the point of this change? > Were you aware of the fail in the guc_submission scenario? > > -- > Cheers, > Arek Hi Arek. Yes, this was prompted by a regression of this subtest in Yocto which uses GuC submission. I root caused it to this same i915 commit from Chris but incorrectly thought that the new "policy" was that sysfs max freq could be ignored in pretty much any situation. I understand now that it should be ignored in only boost and real user wait situations (not those triggered by GuC). So I do agree with this revert. Is there an i915 fix coming soon? Chris? Jeff ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [igt PATCH] igt/pm_rps: Remove remaining assert on CUR <= MAX
From: Jeff McGee This completes the change started by: commit 39cccab83b7c515a2b57abe679a8cb304c8933ef Author: Chris Wilson Date: Fri May 19 09:41:40 2017 +0100 igt/pm_rps: Allow CUR to be greater than MAX (overclocking) Cc: Chris Wilson Signed-off-by: Jeff McGee --- tests/pm_rps.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/pm_rps.c b/tests/pm_rps.c index f0455e78..1a322459 100644 --- a/tests/pm_rps.c +++ b/tests/pm_rps.c @@ -145,7 +145,6 @@ static int do_writeval(FILE *filp, int val, int lerrno, bool readback_check) static void checkit(const int *freqs) { igt_assert_lte(freqs[MIN], freqs[MAX]); - igt_assert_lte(freqs[CUR], freqs[MAX]); igt_assert_lte(freqs[RPn], freqs[CUR]); igt_assert_lte(freqs[RPn], freqs[MIN]); igt_assert_lte(freqs[MAX], freqs[RP0]); -- 2.11.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v6 18/20] drm/i915: Watchdog timeout: DRM kernel interface to set the timeout
On Tue, Apr 18, 2017 at 01:23:33PM -0700, Michel Thierry wrote: > Final enablement patch for GPU hang detection using watchdog timeout. > Using the gem_context_setparam ioctl, users can specify the desired > timeout value in microseconds, and the driver will do the conversion to > 'timestamps'. > > The recommended default watchdog threshold for video engines is 6 us, > since this has been _empirically determined_ to be a good compromise for > low-latency requirements and low rate of false positives. The default > register value is ~106000us and the theoretical max value (all 1s) is > 353 seconds. > > Note, UABI engine ids and i915 engine ids are different, and this patch > uses the i915 ones. Some kind of mapping table [1] is required if we > decide to use the UABI engine ids. > > [1] > http://patchwork.freedesktop.org/patch/msgid/20170329135831.30254-2-ch...@chris-wilson.co.uk > > v2: Fixed get api to return values in microseconds. Threshold updated to > be per context engine. Check for u32 overflow. Capture ctx threshold > value in error state. > > v3: Add a way to get array size, short-cut to disable all thresholds, > return EFAULT / EINVAL as needed. Move the capture of the threshold > value in the error state into a new patch. BXT has a different > timestamp base (because why not?). > > Signed-off-by: Tomas Elf > Signed-off-by: Arun Siluvery > Signed-off-by: Michel Thierry > --- > drivers/gpu/drm/i915/i915_drv.h | 29 + > drivers/gpu/drm/i915/i915_gem_context.c | 102 > > drivers/gpu/drm/i915/intel_lrc.c| 5 +- > include/uapi/drm/i915_drm.h | 1 + > 4 files changed, 135 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index 203f2112dd18..f65a236fddef 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -3574,6 +3574,35 @@ i915_gem_context_lookup_timeline(struct > i915_gem_context *ctx, > return &vm->timeline.engine[engine->id]; > } > > +/* > + * BDW & SKL+ Timestamp timer resolution = 0.080 uSec, > + * or 1250 counts per second, or ~12 counts per microsecond. > + * > + * But Broxton Timestamp timer resolution is different, 0.052 uSec, > + * or 1920 counts per second, or ~19 counts per microsecond. > + */ > +#define SKL_TIMESTAMP_CNTS_PER_USEC 12 > +#define BXT_TIMESTAMP_CNTS_PER_USEC 19 > +#define TIMESTAMP_CNTS_PER_USEC(dev_priv) (IS_BROXTON(dev_priv) ? \ > +BXT_TIMESTAMP_CNTS_PER_USEC : \ > +SKL_TIMESTAMP_CNTS_PER_USEC) > +static inline u32 > +watchdog_to_us(struct drm_i915_private *dev_priv, u32 value_in_clock_counts) > +{ > + return value_in_clock_counts / TIMESTAMP_CNTS_PER_USEC(dev_priv); > +} > + > +static inline u32 > +watchdog_to_clock_counts(struct drm_i915_private *dev_priv, u64 value_in_us) > +{ > + u64 threshold = value_in_us * TIMESTAMP_CNTS_PER_USEC(dev_priv); > + > + if (overflows_type(threshold, u32)) > + return -EINVAL; > + > + return threshold; > +} > + > int i915_perf_open_ioctl(struct drm_device *dev, void *data, >struct drm_file *file); > > diff --git a/drivers/gpu/drm/i915/i915_gem_context.c > b/drivers/gpu/drm/i915/i915_gem_context.c > index edbed85a1c88..85a6467a25a6 100644 > --- a/drivers/gpu/drm/i915/i915_gem_context.c > +++ b/drivers/gpu/drm/i915/i915_gem_context.c > @@ -422,6 +422,102 @@ i915_gem_context_create_gvt(struct drm_device *dev) > return ctx; > } > > +/* Return the timer count threshold in microseconds. */ > +int i915_gem_context_get_watchdog(struct i915_gem_context *ctx, > + struct drm_i915_gem_context_param *args) > +{ > + struct drm_i915_private *dev_priv = ctx->i915; > + struct intel_engine_cs *engine; > + enum intel_engine_id id; > + u32 threshold_in_us[I915_NUM_ENGINES]; > + > + if (args->size == 0) > + goto out; > + > + if (args->size < sizeof(threshold_in_us)) > + return -EFAULT; > + > + if (!dev_priv->engine[VCS]->emit_start_watchdog) > + return -ENODEV; > + > + for_each_engine(engine, dev_priv, id) { > + struct intel_context *ce = &ctx->engine[id]; > + > + threshold_in_us[id] = watchdog_to_us(dev_priv, > + ce->watchdog_threshold); > + } > + > + mutex_unlock(&dev_priv->drm.struct_mutex); > + if (__copy_to_user(u64_to_user_ptr(args->value), > +&threshold_in_us, > +sizeof(threshold_in_us))) { > + mutex_lock(&dev_priv->drm.struct_mutex); > + return -EFAULT; > + } > + mutex_lock(&dev_priv->drm.struct_mutex); > + > +out: > + args->size = sizeof(threshold_in_us); > + > + return 0; > +} > + > +/* > + * Based on time out value in microseconds (
Re: [Intel-gfx] [PATCH 4/8] drm/i915/huc: Add BXT HuC Loading Support
On Mon, Dec 05, 2016 at 12:42:11PM -0800, Srivatsa, Anusha wrote: > > > >-Original Message- > >From: Tvrtko Ursulin [mailto:tvrtko.ursu...@linux.intel.com] > >Sent: Thursday, December 1, 2016 5:11 AM > >To: Srivatsa, Anusha ; intel- > >g...@lists.freedesktop.org > >Subject: Re: [Intel-gfx] [PATCH 4/8] drm/i915/huc: Add BXT HuC Loading > >Support > > > > > >On 30/11/2016 23:31, Anusha Srivatsa wrote: > >> This patch adds the HuC Loading for the BXT by using the updated file > >> construction. > >> > >> Version 1.7 of the HuC firmware. > >> > >> v2: rebased. > >> v3: rebased on top of drm-tip > >> > >> Cc: Jeff Mcgee > >> Signed-off-by: Anusha Srivatsa > >> Reviewed-by: Jeff McGee > >> --- > >> drivers/gpu/drm/i915/intel_huc_loader.c | 11 +++ > >> 1 file changed, 11 insertions(+) > >> > >> diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c > >> b/drivers/gpu/drm/i915/intel_huc_loader.c > >> index 663fcc4..6357c19 100644 > >> --- a/drivers/gpu/drm/i915/intel_huc_loader.c > >> +++ b/drivers/gpu/drm/i915/intel_huc_loader.c > >> @@ -40,6 +40,10 @@ > >> * Note that HuC firmware loading must be done before GuC loading. > >> */ > >> > >> +#define BXT_FW_MAJOR 01 > >> +#define BXT_FW_MINOR 07 > >> +#define BXT_BLD_NUM 1398 > >> + > >> #define SKL_FW_MAJOR 01 > >> #define SKL_FW_MINOR 07 > >> #define SKL_BLD_NUM 1398 > >> @@ -52,6 +56,9 @@ > >>SKL_FW_MINOR, SKL_BLD_NUM) > >> MODULE_FIRMWARE(I915_SKL_HUC_UCODE); > >> > >> +#define I915_BXT_HUC_UCODE HUC_FW_PATH(bxt, BXT_FW_MAJOR, \ > >> + BXT_FW_MINOR, BXT_BLD_NUM) > >> +MODULE_FIRMWARE(I915_BXT_HUC_UCODE); > >> /** > >> * huc_ucode_xfer() - DMA's the firmware > >> * @dev_priv: the drm device > >> @@ -159,6 +166,10 @@ void intel_huc_init(struct drm_device *dev) > >>fw_path = I915_SKL_HUC_UCODE; > >>huc_fw->major_ver_wanted = SKL_FW_MAJOR; > >>huc_fw->minor_ver_wanted = SKL_FW_MINOR; > >> + } else if (IS_BROXTON(dev_priv)) { > >> + fw_path = I915_BXT_HUC_UCODE; > >> + huc_fw->major_ver_wanted = BXT_FW_MAJOR; > >> + huc_fw->minor_ver_wanted = BXT_FW_MINOR; > >>} > >> > >>huc_fw->uc_fw_path = fw_path; > >> > > > >Build number in the file name still worries me. Last time I've asked about > >it the > >thread kind of died off so I will re-state it. > > > >My concern is that if we will be getting firmware releases with the same > >major- > >minor but different build numbers, then embedding the build number into the > >driver prevents loading of a newer firmware unless the kernel is also > >updated. > > > >I am not sure if that is what we want. Perhaps it is not expected at all > >that will > >happen in production so it is not a concern? > > > >Or if it could happen, perhaps we should either push back on the scheme > >- drop the build number and bump the minor in all cases, or alternatively > >for our > >purposes drop the build number from the driver and have a symlinked scheme on > >disk? > > > >Regards, > > > >Tvrtko > > Hi Tvrtko, > Sincere apologies for responding so late. According to my understanding, Jeff > correct me if I am wrong, we are finalizing the firmware version number for > every kernel version. So a certain kernel will have only one possible firware > major-minor and build number for a certain platform. > > I have cc-ed Jeff in this thread so he can add his comment on build number. > Jeff, any comments? > > Regards, > Anusha Sorry for delayed response. I'm checking with HuC firmware team on their intended release model. -Jeff ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915/guc: Drop comment on fwif autogeneration
Reviewed-by: Jeff McGee On Mon, Dec 05, 2016 at 05:04:29PM +0100, Arkadiusz Hiler wrote: > The firmware interface file was initially partially autogenerated, but > this is no longer the case. > > It was never updated automatically, and a lot manual changes were > introduced since. > > From now on any changes to the firmware interface will be managed by > hand, which gives us flexibility when it comes to structure reuse > (HuC/GuC) and naming conventions. > > Cc: Anusha Srivatsa > Cc: Jeff Mcgee > Cc: Sagar A. Kamble > Signed-off-by: Arkadiusz Hiler > --- > drivers/gpu/drm/i915/intel_guc_fwif.h | 9 - > 1 file changed, 9 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h > b/drivers/gpu/drm/i915/intel_guc_fwif.h > index 00ca0df..3202b32 100644 > --- a/drivers/gpu/drm/i915/intel_guc_fwif.h > +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h > @@ -23,15 +23,6 @@ > #ifndef _INTEL_GUC_FWIF_H > #define _INTEL_GUC_FWIF_H > > -/* > - * This file is partially autogenerated, although currently with some manual > - * fixups afterwards. In future, it should be entirely autogenerated, in > order > - * to ensure that the definitions herein remain in sync with those used by > the > - * GuC's own firmware. > - * > - * EDITING THIS FILE IS THEREFORE NOT RECOMMENDED - YOUR CHANGES MAY BE LOST. > - */ > - > #define GFXCORE_FAMILY_GEN9 12 > #define GFXCORE_FAMILY_UNKNOWN 0x7fff > > -- > 2.7.4 > ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams
On Wed, Nov 23, 2016 at 02:27:43PM -0800, Anusha Srivatsa wrote: > From: Peter Antoine > > This patch will allow for getparams to return the status of the HuC. > As the HuC has to be validated by the GuC this patch uses the validated > status to show when the HuC is loaded and ready for use. You cannot use > the loaded status as with the GuC as the HuC is verified after it is > loaded and is not usable until it is verified. > > v2: removed the forewakes as the registers are already force-woken. > (T.Ursulin) > v4: rebased. > v5: rebased. > v6: rebased. > v7: rebased. > v8: rebased. > > Tested-by: Xiang Haihao > Signed-off-by: Anusha Srivatsa > Signed-off-by: Peter Antoine > Reviewed-by: Rodrigo Vivi > Reviewed-by: Jeff McGee > --- > drivers/gpu/drm/i915/i915_drv.c | 8 > drivers/gpu/drm/i915/intel_huc.h| 1 + > drivers/gpu/drm/i915/intel_huc_loader.c | 13 + > include/uapi/drm/i915_drm.h | 1 + > 4 files changed, 23 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c > index b893e67..f2d5b0f 100644 > --- a/drivers/gpu/drm/i915/i915_drv.c > +++ b/drivers/gpu/drm/i915/i915_drv.c > @@ -49,6 +49,8 @@ > #include "i915_trace.h" > #include "i915_vgpu.h" > #include "intel_drv.h" > +#include "intel_guc.h" > +#include "intel_huc.h" > > static struct drm_driver driver; > > @@ -350,6 +352,9 @@ static int i915_getparam(struct drm_device *dev, void > *data, >*/ > value = 1; > break; > + case I915_PARAM_HAS_HUC: > + value = intel_is_huc_valid(dev_priv); > + break; > default: > DRM_DEBUG("Unknown parameter %d\n", param->param); > return -EINVAL; > @@ -603,6 +608,7 @@ static int i915_load_modeset_init(struct drm_device *dev) > if (ret) > goto cleanup_irq; > > + intel_huc_init(dev); As we discussed, this needs to be in patch 3. > intel_guc_init(dev); > > ret = i915_gem_init(dev); > @@ -630,6 +636,7 @@ static int i915_load_modeset_init(struct drm_device *dev) > DRM_ERROR("failed to idle hardware; continuing to unload!\n"); > i915_gem_fini(dev_priv); > cleanup_irq: > + intel_huc_fini(dev); > intel_guc_fini(dev); > drm_irq_uninstall(dev); > intel_teardown_gmbus(dev); > @@ -1325,6 +1332,7 @@ void i915_driver_unload(struct drm_device *dev) > /* Flush any outstanding unpin_work. */ > drain_workqueue(dev_priv->wq); > > + intel_huc_fini(dev); > intel_guc_fini(dev); > i915_gem_fini(dev_priv); > intel_fbc_cleanup_cfb(dev_priv); > diff --git a/drivers/gpu/drm/i915/intel_huc.h > b/drivers/gpu/drm/i915/intel_huc.h > index 3ce0299..2e150be 100644 > --- a/drivers/gpu/drm/i915/intel_huc.h > +++ b/drivers/gpu/drm/i915/intel_huc.h > @@ -39,4 +39,5 @@ struct intel_huc { > void intel_huc_init(struct drm_device *dev); > void intel_huc_fini(struct drm_device *dev); > int intel_huc_load(struct drm_device *dev); > +extern int intel_is_huc_valid(struct drm_i915_private *dev_priv); > #endif > diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c > b/drivers/gpu/drm/i915/intel_huc_loader.c > index 3a2555e..8c3993b 100644 > --- a/drivers/gpu/drm/i915/intel_huc_loader.c > +++ b/drivers/gpu/drm/i915/intel_huc_loader.c > @@ -291,3 +291,16 @@ void intel_huc_fini(struct drm_device *dev) > > huc_fw->fetch_status = UC_FIRMWARE_NONE; > } > + > +/** > + * intel_is_huc_valid() - Check to see if the HuC is fully loaded. > + * @dev_priv:drm device to check. > + * > + * This function will return true if the guc has been loaded and > + * has valid firmware. The simplest way of doing this is to check > + * if the HuC has been validated, if so it must have been loaded. > + */ > +int intel_is_huc_valid(struct drm_i915_private *dev_priv) > +{ > + return ((I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED) != 0); > +} > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h > index bdfc688..0a9dac4 100644 > --- a/include/uapi/drm/i915_drm.h > +++ b/include/uapi/drm/i915_drm.h > @@ -390,6 +390,7 @@ typedef struct drm_i915_irq_wait { > #define I915_PARAM_HAS_POOLED_EU 38 > #define I915_PARAM_MIN_EU_IN_POOL 39 > #define I915_PARAM_MMAP_GTT_VERSION 40 > +#define I915_PARAM_HAS_HUC42 > > /* Query whether DRM_I915_GEM_EXECBUFFER2 supports user defined execution > * priorities and the driver will attempt to execute batches in priority > order. > -- > 2.7.4 > > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915/GuC: Combine the two kernel parameter into one
On Tue, Nov 15, 2016 at 10:06:47AM -0800, Srivatsa, Anusha wrote: > > > >-Original Message- > >From: Tvrtko Ursulin [mailto:tvrtko.ursu...@linux.intel.com] > >Sent: Tuesday, November 15, 2016 2:31 AM > >To: Srivatsa, Anusha ; Mcgee, Jeff > > > >Cc: Ursulin, Tvrtko ; > >intel-gfx@lists.freedesktop.org; > >Vivi, Rodrigo > >Subject: Re: [Intel-gfx] [PATCH] drm/i915/GuC: Combine the two kernel > >parameter into one > > > > > >On 14/11/2016 17:34, Srivatsa, Anusha wrote: > > > >[snip] > > > >>> One idea could be to hide the guc loading form the user altogether > >>> and hence improve usability (decrease exposed complexity) by having > >>> only two parameters; i915.enable_guc_scheduling and i915.enable_huc. > >> That's a good point. But with this we will have two parameters (which > >> kills the > >point of why the patch was written in the first place), then we can rather > >leave it > >the way it is. Right? > > > >For some reason I thought the HuC patch series add a another module > >parameter. > > > >What is the failure mode for HuC is GuC firmware loading is disabled btw? > > > Hi Tvrtko, in the function intel_guc_auth_huc() there is a check to see if > GuC is loaded or not. If GuC loading has failed or loading is disabled, then > HuC authentication does not happen. > Yes, GuC must authenticate HuC firmware. I am in favor of Tvrtko's suggestion for dropping i915.enable_guc_loading, keeping i915.enable_guc_submission, and adding i915.enable_huc. If either of the last two are enabled, GuC loading is implied. So kernel parameters are tied to enabling specific functionality. I think the specific parameter for loading is legacy from the first hurdle for GuC long ago. I assume we are not bound by ABI to keep that around if it is no longer needed, yes? The other thing I would want to reconsider is the "casual" enable vs. "force" enable options. Does anyone remember why these 2 levels of enable have been used. Maybe this is also a legacy. Can we just do a auto (-1), disable (0), and enable (1)? ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH-v11] drm/i915/huc: Add HuC fw loading support
On Tue, Nov 15, 2016 at 10:26:46AM +, Tvrtko Ursulin wrote: > > On 15/11/2016 00:39, Anusha Srivatsa wrote: > >From: Peter Antoine > > > >The HuC loading process is similar to GuC. The intel_uc_fw_fetch() > >is used for both cases. > > > >HuC loading needs to be before GuC loading. The WOPCM setting must > >be done early before loading any of them. > > > >v2: rebased on-top of drm-intel-nightly. > >removed if(HAS_GUC()) before the guc call. (D.Gordon) > >update huc_version number of format. > >v3: rebased to drm-intel-nightly, changed the file name format to > >match the one in the huc package. > >Changed dev->dev_private to to_i915() > >v4: moved function back to where it was. > >change wait_for_atomic to wait_for. > >v5: rebased + comment changes. > >v7: rebased. > >v8: rebased. > >v9: rebased. Changed the year in the copyright message to reflect > >the right year.Correct the comments,remove the unwanted WARN message, > >replace drm_gem_object_unreference() with i915_gem_object_put().Make the > >prototypes in intel_huc.h non-extern. > >v10: rebased. Update the file construction done by HuC. It is similar to > >GuC.Adopted the approach used in- > >https://patchwork.freedesktop.org/patch/104355/ > >v11: Fix warnings. Remove old declaration. > > > >Cc: Tvrtko Ursulin > >Tested-by: Xiang Haihao > >Signed-off-by: Anusha Srivatsa > >Signed-off-by: Alex Dai > >Signed-off-by: Peter Antoine > >Reviewed-by: Dave Gordon > >--- > > drivers/gpu/drm/i915/Makefile | 1 + > > drivers/gpu/drm/i915/i915_drv.h | 3 + > > drivers/gpu/drm/i915/i915_guc_reg.h | 3 + > > drivers/gpu/drm/i915/intel_guc.h| 1 + > > drivers/gpu/drm/i915/intel_guc_loader.c | 6 +- > > drivers/gpu/drm/i915/intel_huc.h| 42 + > > drivers/gpu/drm/i915/intel_huc_loader.c | 269 > > > > 7 files changed, 323 insertions(+), 2 deletions(-) > > create mode 100644 drivers/gpu/drm/i915/intel_huc.h > > create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c > > > >diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > >index 3dea46a..cfea925 100644 > >--- a/drivers/gpu/drm/i915/Makefile > >+++ b/drivers/gpu/drm/i915/Makefile > >@@ -56,6 +56,7 @@ i915-y += i915_cmd_parser.o \ > > > > # general-purpose microcontroller (GuC) support > > i915-y += intel_guc_loader.o \ > >+ intel_huc_loader.o \ > > i915_guc_submission.o > > > > # autogenerated null render state > >diff --git a/drivers/gpu/drm/i915/i915_drv.h > >b/drivers/gpu/drm/i915/i915_drv.h > >index c4a14de..3a6c412 100644 > >--- a/drivers/gpu/drm/i915/i915_drv.h > >+++ b/drivers/gpu/drm/i915/i915_drv.h > >@@ -56,6 +56,7 @@ > > #include "intel_bios.h" > > #include "intel_dpll_mgr.h" > > #include "intel_guc.h" > >+#include "intel_huc.h" > > #include "intel_lrc.h" > > #include "intel_ringbuffer.h" > > > >@@ -1791,6 +1792,7 @@ struct drm_i915_private { > > > > struct intel_gvt *gvt; > > > >+struct intel_huc huc; > > struct intel_guc guc; > > > > struct intel_csr csr; > >@@ -2607,6 +2609,7 @@ struct drm_i915_cmd_table { > > #define HAS_GUC(dev_priv) ((dev_priv)->info.has_guc) > > #define HAS_GUC_UCODE(dev_priv) (HAS_GUC(dev_priv)) > > #define HAS_GUC_SCHED(dev_priv) (HAS_GUC(dev_priv)) > >+#define HAS_HUC_UCODE(dev) (HAS_GUC(dev)) > > Parameter name should be dev_priv. > > > #define HAS_RESOURCE_STREAMER(dev_priv) > > ((dev_priv)->info.has_resource_streamer) > > > >diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h > >b/drivers/gpu/drm/i915/i915_guc_reg.h > >index a47e1e4..64e942a 100644 > >--- a/drivers/gpu/drm/i915/i915_guc_reg.h > >+++ b/drivers/gpu/drm/i915/i915_guc_reg.h > >@@ -61,9 +61,12 @@ > > #define DMA_ADDRESS_SPACE_GTT (8 << 16) > > #define DMA_COPY_SIZE _MMIO(0xc310) > > #define DMA_CTRL_MMIO(0xc314) > >+#define HUC_UKERNEL (1<<9) > > #define UOS_MOVE(1<<4) > > #define START_DMA (1<<0) > > #define DMA_GUC_WOPCM_OFFSET_MMIO(0xc340) > >+#define HUC_LOADING_AGENT_VCR (0<<1) > >+#define HUC_LOADING_AGENT_GUC (1<<1) > > #define GUC_WOPCM_OFFSET_VALUE 0x8 /* 512KB */ > > #define GUC_MAX_IDLE_COUNT _MMIO(0xC3E4) > > > >diff --git a/drivers/gpu/drm/i915/intel_guc.h > >b/drivers/gpu/drm/i915/intel_guc.h > >index 46990a0..338e803 100644 > >--- a/drivers/gpu/drm/i915/intel_guc.h > >+++ b/drivers/gpu/drm/i915/intel_guc.h > >@@ -184,6 +184,7 @@ extern const char *intel_uc_fw_status_repr(enum > >intel_uc_fw_status status); > > extern int intel_guc_suspend(struct drm_device *dev); > > extern int intel_guc_resume(struct drm_device *dev); > > void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw); > >+u32 guc_wopcm_size(struct drm_i915_private *dev_priv); > > > > /* i915_guc_submission.c */ > > int i915_guc_submission_init(st
Re: [Intel-gfx] [PATCH] drm/i915/GuC: Combine the two kernel parameter into one
On Wed, Nov 09, 2016 at 11:11:07AM -0800, Anusha Srivatsa wrote: > Replace i915.enable_guc_loading and i915.enable_guc_submission > with a single parameter - i915.enable_guc. Where: > > -1 : Platform default (Only load GuC) > 0 : Do not use GuC > 1 : Load GuC, do not use Command Submission through GuC > 2 : Load and use GuC for Command Submission > I think this approach could get ugly as we add more GuC functionality and the list of combinations under this one parameter grows. What is the issue we are trying to solve? I thought it was that folks didn't like that we had an option to just load GuC and do nothing with it. Can those folks please comment? Jeff > Cc: Tvrtko Ursulin > Cc: Jeff Mcgee > Cc: Rodrigo Vivi > Signed-off-by: Anusha Srivatsa > --- > drivers/gpu/drm/i915/i915_guc_submission.c | 16 +--- > drivers/gpu/drm/i915/i915_params.c | 17 + > drivers/gpu/drm/i915/i915_params.h | 3 +-- > drivers/gpu/drm/i915/intel_guc.h | 2 ++ > drivers/gpu/drm/i915/intel_guc_loader.c| 39 > +++--- > drivers/gpu/drm/i915/intel_lrc.c | 14 --- > 6 files changed, 56 insertions(+), 35 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c > b/drivers/gpu/drm/i915/i915_guc_submission.c > index 7809acf..a5ef268 100644 > --- a/drivers/gpu/drm/i915/i915_guc_submission.c > +++ b/drivers/gpu/drm/i915/i915_guc_submission.c > @@ -1471,13 +1471,15 @@ int i915_guc_submission_init(struct drm_i915_private > *dev_priv) > const size_t poolsize = GUC_MAX_GPU_CONTEXTS * ctxsize; > const size_t gemsize = round_up(poolsize, PAGE_SIZE); > struct intel_guc *guc = &dev_priv->guc; > + struct intel_uc_fw *guc_fw = &dev_priv->guc.guc_fw; > + > struct i915_vma *vma; > > /* Wipe bitmap & delete client in case of reinitialisation */ > bitmap_clear(guc->doorbell_bitmap, 0, GUC_MAX_DOORBELLS); > i915_guc_submission_disable(dev_priv); > > - if (!i915.enable_guc_submission) > + if (!guc_fw->enable_guc_submission) > return 0; /* not enabled */ > > if (guc->ctx_pool_vma) > @@ -1629,7 +1631,9 @@ void i915_guc_capture_logs(struct drm_i915_private > *dev_priv) > > void i915_guc_flush_logs(struct drm_i915_private *dev_priv) > { > - if (!i915.enable_guc_submission || (i915.guc_log_level < 0)) > + struct intel_uc_fw *guc_fw = &dev_priv->guc.guc_fw; > + > + if (!guc_fw->enable_guc_submission || (i915.guc_log_level < 0)) > return; > > /* First disable the interrupts, will be renabled afterwards */ > @@ -1649,7 +1653,9 @@ void i915_guc_flush_logs(struct drm_i915_private > *dev_priv) > > void i915_guc_unregister(struct drm_i915_private *dev_priv) > { > - if (!i915.enable_guc_submission) > + struct intel_uc_fw *guc_fw = &dev_priv->guc.guc_fw; > + > + if (!guc_fw->enable_guc_submission) > return; > > mutex_lock(&dev_priv->drm.struct_mutex); > @@ -1659,7 +1665,9 @@ void i915_guc_unregister(struct drm_i915_private > *dev_priv) > > void i915_guc_register(struct drm_i915_private *dev_priv) > { > - if (!i915.enable_guc_submission) > + struct intel_uc_fw *guc_fw = &dev_priv->guc.guc_fw; > + > + if (!guc_fw->enable_guc_submission) > return; > > mutex_lock(&dev_priv->drm.struct_mutex); > diff --git a/drivers/gpu/drm/i915/i915_params.c > b/drivers/gpu/drm/i915/i915_params.c > index 629e433..4600f83 100644 > --- a/drivers/gpu/drm/i915/i915_params.c > +++ b/drivers/gpu/drm/i915/i915_params.c > @@ -56,8 +56,7 @@ struct i915_params i915 __read_mostly = { > .verbose_state_checks = 1, > .nuclear_pageflip = 0, > .edp_vswing = 0, > - .enable_guc_loading = 0, > - .enable_guc_submission = 0, > + .enable_guc = 0, > .guc_log_level = -1, > .enable_dp_mst = true, > .inject_load_failure = 0, > @@ -215,15 +214,11 @@ MODULE_PARM_DESC(edp_vswing, >"(0=use value from vbt [default], 1=low power swing(200mV)," >"2=default swing(400mV))"); > > -module_param_named_unsafe(enable_guc_loading, i915.enable_guc_loading, int, > 0400); > -MODULE_PARM_DESC(enable_guc_loading, > - "Enable GuC firmware loading " > - "(-1=auto, 0=never [default], 1=if available, 2=required)"); > - > -module_param_named_unsafe(enable_guc_submission, i915.enable_guc_submission, > int, 0400); > -MODULE_PARM_DESC(enable_guc_submission, > - &quo
Re: [Intel-gfx] [PATCH 5/8] drm/i915/HuC: Add KBL huC loading Support
Reviewed-by: Jeff McGee On Thu, Nov 10, 2016 at 04:15:18PM -0800, Anusha Srivatsa wrote: > This patch adds the support to load HuC on KBL > Version 2.0 > > Cc: Jeff Mcgee > Signed-off-by: Anusha Srivatsa > --- > drivers/gpu/drm/i915/intel_huc_loader.c | 15 ++- > 1 file changed, 14 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c > b/drivers/gpu/drm/i915/intel_huc_loader.c > index 5a7ce65..dab64ba 100644 > --- a/drivers/gpu/drm/i915/intel_huc_loader.c > +++ b/drivers/gpu/drm/i915/intel_huc_loader.c > @@ -49,6 +49,10 @@ > #define BXT_FW_MINOR 07 > #define BXT_BLD_NUM 1398 > > +#define KBL_FW_MAJOR 02 > +#define KBL_FW_MINOR 00 > +#define KBL_BLD_NUM 1810 > + > #define HUC_FW_PATH(platform, major, minor, bld_num) \ > "i915/" __stringify(platform) "_huc_ver" __stringify(major) "_" \ > __stringify(minor) "_" __stringify(bld_num) ".bin" > @@ -60,6 +64,11 @@ MODULE_FIRMWARE(I915_SKL_HUC_UCODE); > #define I915_BXT_HUC_UCODE HUC_FW_PATH(bxt, BXT_FW_MAJOR, \ > BXT_FW_MINOR, BXT_BLD_NUM) > MODULE_FIRMWARE(I915_BXT_HUC_UCODE); > + > +#define I915_KBL_HUC_UCODE HUC_FW_PATH(kbl, KBL_FW_MAJOR, \ > + KBL_FW_MINOR, KBL_BLD_NUM) > +MODULE_FIRMWARE(I915_KBL_HUC_UCODE); > + > /** > * huc_ucode_xfer() - DMA's the firmware > * @dev_priv: the drm device > @@ -171,8 +180,12 @@ void intel_huc_init(struct drm_device *dev) > fw_path = I915_BXT_HUC_UCODE; > huc_fw->major_ver_wanted = BXT_FW_MAJOR; > huc_fw->minor_ver_wanted = BXT_FW_MINOR; > + } else if (IS_KABYLAKE(dev_priv)) { > + fw_path = I915_KBL_HUC_UCODE; > + huc_fw->major_ver_wanted = KBL_FW_MAJOR; > + huc_fw->minor_ver_wanted = KBL_FW_MINOR; > } > - > + > if (fw_path == NULL) > return; > > -- > 2.7.4 > ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 4/8] drm/i915/huc: Add BXT HuC Loading Support
Reviewed-by: Jeff McGee On Thu, Nov 10, 2016 at 04:15:17PM -0800, Anusha Srivatsa wrote: > This patch adds the HuC Loading for the BXT by using > the updated file construction. > > Version 1.7 of the HuC firmware. > > Cc: Jeff Mcgee > Signed-off-by: Anusha Srivatsa > --- > drivers/gpu/drm/i915/intel_huc_loader.c | 13 - > 1 file changed, 12 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c > b/drivers/gpu/drm/i915/intel_huc_loader.c > index 8d2b6ab..5a7ce65 100644 > --- a/drivers/gpu/drm/i915/intel_huc_loader.c > +++ b/drivers/gpu/drm/i915/intel_huc_loader.c > @@ -45,6 +45,10 @@ > #define SKL_BLD_NUM 1398 > #define I915_SKL_HUC_UCODE "i915/skl_huc_ver01_07_1398.bin" > > +#define BXT_FW_MAJOR 01 > +#define BXT_FW_MINOR 07 > +#define BXT_BLD_NUM 1398 > + > #define HUC_FW_PATH(platform, major, minor, bld_num) \ > "i915/" __stringify(platform) "_huc_ver" __stringify(major) "_" \ > __stringify(minor) "_" __stringify(bld_num) ".bin" > @@ -53,6 +57,9 @@ > SKL_FW_MINOR, SKL_BLD_NUM) > MODULE_FIRMWARE(I915_SKL_HUC_UCODE); > > +#define I915_BXT_HUC_UCODE HUC_FW_PATH(bxt, BXT_FW_MAJOR, \ > + BXT_FW_MINOR, BXT_BLD_NUM) > +MODULE_FIRMWARE(I915_BXT_HUC_UCODE); > /** > * huc_ucode_xfer() - DMA's the firmware > * @dev_priv: the drm device > @@ -160,7 +167,11 @@ void intel_huc_init(struct drm_device *dev) > fw_path = I915_SKL_HUC_UCODE; > huc_fw->major_ver_wanted = SKL_FW_MAJOR; > huc_fw->minor_ver_wanted = SKL_FW_MINOR; > - } > + } else if (IS_BROXTON(dev_priv)) { > + fw_path = I915_BXT_HUC_UCODE; > + huc_fw->major_ver_wanted = BXT_FW_MAJOR; > + huc_fw->minor_ver_wanted = BXT_FW_MINOR; > + } > > if (fw_path == NULL) > return; > -- > 2.7.4 > ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 3/8] drm/i915/huc: Add HuC fw loading support
On Fri, Nov 11, 2016 at 06:05:34PM -0800, Jeff McGee wrote: > On Thu, Nov 10, 2016 at 04:15:16PM -0800, Anusha Srivatsa wrote: > > From: Peter Antoine > > > > The HuC loading process is similar to GuC. The intel_uc_fw_fetch() > > is used for both cases. > > > > HuC loading needs to be before GuC loading. The WOPCM setting must > > be done early before loading any of them. > > > > v2: rebased on-top of drm-intel-nightly. > > removed if(HAS_GUC()) before the guc call. (D.Gordon) > > update huc_version number of format. > > v3: rebased to drm-intel-nightly, changed the file name format to > > match the one in the huc package. > > Changed dev->dev_private to to_i915() > > v4: moved function back to where it was. > > change wait_for_atomic to wait_for. > > v5: rebased + comment changes. > > v7: rebased. > > v8: rebased. > > v9: rebased. Changed the year in the copyright message to reflect > > the right year.Correct the comments,remove the unwanted WARN message, > > replace drm_gem_object_unreference() with i915_gem_object_put().Make the > > prototypes in intel_huc.h non-extern. > > v10: rebased. Update the file construction done by HuC. It is similar to > > GuC.Adopted the approach used in- > > https://patchwork.freedesktop.org/patch/104355/ > > > > Cc: Tvrtko Ursulin > > Tested-by: Xiang Haihao > > Signed-off-by: Anusha Srivatsa > > Signed-off-by: Alex Dai > > Signed-off-by: Peter Antoine > > Reviewed-by: Dave Gordon > > --- > > drivers/gpu/drm/i915/Makefile | 1 + > > drivers/gpu/drm/i915/i915_drv.h | 3 + > > drivers/gpu/drm/i915/i915_guc_reg.h | 3 + > > drivers/gpu/drm/i915/intel_guc.h| 1 + > > drivers/gpu/drm/i915/intel_guc_loader.c | 6 +- > > drivers/gpu/drm/i915/intel_huc.h| 42 + > > drivers/gpu/drm/i915/intel_huc_loader.c | 270 > > > > 7 files changed, 324 insertions(+), 2 deletions(-) > > create mode 100644 drivers/gpu/drm/i915/intel_huc.h > > create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c > > > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > > index 0857e50..c99b0ee 100644 > > --- a/drivers/gpu/drm/i915/Makefile > > +++ b/drivers/gpu/drm/i915/Makefile > > @@ -55,6 +55,7 @@ i915-y += i915_cmd_parser.o \ > > > > # general-purpose microcontroller (GuC) support > > i915-y += intel_guc_loader.o \ > > + intel_huc_loader.o \ > > i915_guc_submission.o > > > > # autogenerated null render state > > diff --git a/drivers/gpu/drm/i915/i915_drv.h > > b/drivers/gpu/drm/i915/i915_drv.h > > index 30777de..ebef982 100644 > > --- a/drivers/gpu/drm/i915/i915_drv.h > > +++ b/drivers/gpu/drm/i915/i915_drv.h > > @@ -56,6 +56,7 @@ > > #include "intel_bios.h" > > #include "intel_dpll_mgr.h" > > #include "intel_guc.h" > > +#include "intel_huc.h" > > #include "intel_lrc.h" > > #include "intel_ringbuffer.h" > > > > @@ -1804,6 +1805,7 @@ struct drm_i915_private { > > > > struct intel_gvt *gvt; > > > > + struct intel_huc huc; > > struct intel_guc guc; > > > > struct intel_csr csr; > > @@ -2928,6 +2930,7 @@ struct drm_i915_cmd_table { > > #define HAS_GUC(dev) (INTEL_INFO(dev)->has_guc) > > #define HAS_GUC_UCODE(dev) (HAS_GUC(dev)) > > #define HAS_GUC_SCHED(dev) (HAS_GUC(dev)) > > +#define HAS_HUC_UCODE(dev) (HAS_GUC(dev)) > > > > #define HAS_RESOURCE_STREAMER(dev) (INTEL_INFO(dev)->has_resource_streamer) > > > > diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h > > b/drivers/gpu/drm/i915/i915_guc_reg.h > > index a47e1e4..64e942a 100644 > > --- a/drivers/gpu/drm/i915/i915_guc_reg.h > > +++ b/drivers/gpu/drm/i915/i915_guc_reg.h > > @@ -61,9 +61,12 @@ > > #define DMA_ADDRESS_SPACE_GTT (8 << 16) > > #define DMA_COPY_SIZE _MMIO(0xc310) > > #define DMA_CTRL _MMIO(0xc314) > > +#define HUC_UKERNEL(1<<9) > > #define UOS_MOVE (1<<4) > > #define START_DMA (1<<0) > > #define DMA_GUC_WOPCM_OFFSET _MMIO(0xc340) > > +#define HUC_LOADING_AGENT_VCR (0<<1) > > +#define HUC_LOADING_AGENT_GUC (1<<1) > > #define GUC_WO
Re: [Intel-gfx] [PATCH 3/8] drm/i915/huc: Add HuC fw loading support
On Thu, Nov 10, 2016 at 04:15:16PM -0800, Anusha Srivatsa wrote: > From: Peter Antoine > > The HuC loading process is similar to GuC. The intel_uc_fw_fetch() > is used for both cases. > > HuC loading needs to be before GuC loading. The WOPCM setting must > be done early before loading any of them. > > v2: rebased on-top of drm-intel-nightly. > removed if(HAS_GUC()) before the guc call. (D.Gordon) > update huc_version number of format. > v3: rebased to drm-intel-nightly, changed the file name format to > match the one in the huc package. > Changed dev->dev_private to to_i915() > v4: moved function back to where it was. > change wait_for_atomic to wait_for. > v5: rebased + comment changes. > v7: rebased. > v8: rebased. > v9: rebased. Changed the year in the copyright message to reflect > the right year.Correct the comments,remove the unwanted WARN message, > replace drm_gem_object_unreference() with i915_gem_object_put().Make the > prototypes in intel_huc.h non-extern. > v10: rebased. Update the file construction done by HuC. It is similar to > GuC.Adopted the approach used in- > https://patchwork.freedesktop.org/patch/104355/ > > Cc: Tvrtko Ursulin > Tested-by: Xiang Haihao > Signed-off-by: Anusha Srivatsa > Signed-off-by: Alex Dai > Signed-off-by: Peter Antoine > Reviewed-by: Dave Gordon > --- > drivers/gpu/drm/i915/Makefile | 1 + > drivers/gpu/drm/i915/i915_drv.h | 3 + > drivers/gpu/drm/i915/i915_guc_reg.h | 3 + > drivers/gpu/drm/i915/intel_guc.h| 1 + > drivers/gpu/drm/i915/intel_guc_loader.c | 6 +- > drivers/gpu/drm/i915/intel_huc.h| 42 + > drivers/gpu/drm/i915/intel_huc_loader.c | 270 > > 7 files changed, 324 insertions(+), 2 deletions(-) > create mode 100644 drivers/gpu/drm/i915/intel_huc.h > create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > index 0857e50..c99b0ee 100644 > --- a/drivers/gpu/drm/i915/Makefile > +++ b/drivers/gpu/drm/i915/Makefile > @@ -55,6 +55,7 @@ i915-y += i915_cmd_parser.o \ > > # general-purpose microcontroller (GuC) support > i915-y += intel_guc_loader.o \ > + intel_huc_loader.o \ > i915_guc_submission.o > > # autogenerated null render state > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index 30777de..ebef982 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -56,6 +56,7 @@ > #include "intel_bios.h" > #include "intel_dpll_mgr.h" > #include "intel_guc.h" > +#include "intel_huc.h" > #include "intel_lrc.h" > #include "intel_ringbuffer.h" > > @@ -1804,6 +1805,7 @@ struct drm_i915_private { > > struct intel_gvt *gvt; > > + struct intel_huc huc; > struct intel_guc guc; > > struct intel_csr csr; > @@ -2928,6 +2930,7 @@ struct drm_i915_cmd_table { > #define HAS_GUC(dev) (INTEL_INFO(dev)->has_guc) > #define HAS_GUC_UCODE(dev) (HAS_GUC(dev)) > #define HAS_GUC_SCHED(dev) (HAS_GUC(dev)) > +#define HAS_HUC_UCODE(dev) (HAS_GUC(dev)) > > #define HAS_RESOURCE_STREAMER(dev) (INTEL_INFO(dev)->has_resource_streamer) > > diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h > b/drivers/gpu/drm/i915/i915_guc_reg.h > index a47e1e4..64e942a 100644 > --- a/drivers/gpu/drm/i915/i915_guc_reg.h > +++ b/drivers/gpu/drm/i915/i915_guc_reg.h > @@ -61,9 +61,12 @@ > #define DMA_ADDRESS_SPACE_GTT(8 << 16) > #define DMA_COPY_SIZE_MMIO(0xc310) > #define DMA_CTRL _MMIO(0xc314) > +#define HUC_UKERNEL (1<<9) > #define UOS_MOVE (1<<4) > #define START_DMA(1<<0) > #define DMA_GUC_WOPCM_OFFSET _MMIO(0xc340) > +#define HUC_LOADING_AGENT_VCR(0<<1) > +#define HUC_LOADING_AGENT_GUC(1<<1) > #define GUC_WOPCM_OFFSET_VALUE 0x8 /* 512KB */ > #define GUC_MAX_IDLE_COUNT _MMIO(0xC3E4) > > diff --git a/drivers/gpu/drm/i915/intel_guc.h > b/drivers/gpu/drm/i915/intel_guc.h > index 45dfa40..ff6aba6 100644 > --- a/drivers/gpu/drm/i915/intel_guc.h > +++ b/drivers/gpu/drm/i915/intel_guc.h > @@ -183,6 +183,7 @@ extern const char *intel_uc_fw_status_repr(enum > intel_uc_fw_status status); > extern int intel_guc_suspend(struct drm_device *dev); > extern int intel_guc_resume(struct drm_device *dev); > void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw); > +u32 guc_wopcm_size(struct drm_i915_private *dev_priv); > > /* i915_guc_submission.c */ > int i915_guc_submission_init(struct drm_i915_private *dev_priv); > diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c > b/drivers/gpu/drm/i915/intel_guc_loader.c > index ff26d2c..dc79968 100644 > --- a/drivers/gpu/drm/i915/intel_guc_loader.c > +++ b/drivers/gpu/drm/i915/intel_guc_loader.c > @@ -3
Re: [Intel-gfx] [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general
When updating a patch set on the mailing list with new revisions it is preferred to send those new patches as a reply to the patch being revised and also to include the V2, V3, etc. in the subject. If you have massive changes then it is OK to submit a new set but it helps to include cover letter and version its subject as above to help distinquish from previous sets. Look through the mailing list and you will see examples of both scenarios. I think the protocol is also that if you revise a patch heavily then you cannot carry the r-b tags given on the earlier patch but rather you should get those people to re-review. Daniel - these best practices are recorded somewhere, right? Jeff On Wed, Nov 09, 2016 at 10:51:30AM -0800, Anusha Srivatsa wrote: > From: Peter Antoine > > Rename some of the GuC fw loading code to make them more general. We > will utilise them for HuC loading as well. > s/intel_guc_fw/intel_uc_fw/g > s/GUC_FIRMWARE/UC_FIRMWARE/g > > Struct intel_guc_fw is renamed to intel_uc_fw. Prefix of tts members, > such as 'guc' or 'guc_fw' either is renamed to 'uc' or removed for > same purpose. > > v2: rebased on top of nightly. > reapplied the search/replace as upstream code as changed. > v3: rebased again on drm-nightly. > v4: removed G from messages in shared fw fetch function. > v5: rebased. > v7: rebased. > v8: rebased. > v9: rebased. > v10: rebased. > > Signed-off-by: Anusha Srivatsa > Signed-off-by: Alex Dai > Signed-off-by: Peter Antoine > Reviewed-by: Dave Gordon > Reviewed-by: Jeff McGee > Reviewed-by: Carlos Santa > Tested-by: Carlos Santa > --- > drivers/gpu/drm/i915/i915_debugfs.c| 12 +-- > drivers/gpu/drm/i915/i915_guc_submission.c | 4 +- > drivers/gpu/drm/i915/intel_guc.h | 39 > drivers/gpu/drm/i915/intel_guc_loader.c| 156 > ++--- > 4 files changed, 106 insertions(+), 105 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c > b/drivers/gpu/drm/i915/i915_debugfs.c > index b681d42..7e206dd 100644 > --- a/drivers/gpu/drm/i915/i915_debugfs.c > +++ b/drivers/gpu/drm/i915/i915_debugfs.c > @@ -2353,7 +2353,7 @@ static int i915_llc(struct seq_file *m, void *data) > static int i915_guc_load_status_info(struct seq_file *m, void *data) > { > struct drm_i915_private *dev_priv = node_to_i915(m->private); > - struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw; > + struct intel_uc_fw *guc_fw = &dev_priv->guc.guc_fw; > u32 tmp, i; > > if (!HAS_GUC_UCODE(dev_priv)) > @@ -2361,15 +2361,15 @@ static int i915_guc_load_status_info(struct seq_file > *m, void *data) > > seq_printf(m, "GuC firmware status:\n"); > seq_printf(m, "\tpath: %s\n", > - guc_fw->guc_fw_path); > + guc_fw->uc_fw_path); > seq_printf(m, "\tfetch: %s\n", > - intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status)); > + intel_uc_fw_status_repr(guc_fw->fetch_status)); > seq_printf(m, "\tload: %s\n", > - intel_guc_fw_status_repr(guc_fw->guc_fw_load_status)); > + intel_uc_fw_status_repr(guc_fw->load_status)); > seq_printf(m, "\tversion wanted: %d.%d\n", > - guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted); > + guc_fw->major_ver_wanted, guc_fw->minor_ver_wanted); > seq_printf(m, "\tversion found: %d.%d\n", > - guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found); > + guc_fw->major_ver_found, guc_fw->minor_ver_found); > seq_printf(m, "\theader: offset is %d; size = %d\n", > guc_fw->header_offset, guc_fw->header_size); > seq_printf(m, "\tuCode: offset is %d; size = %d\n", > diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c > b/drivers/gpu/drm/i915/i915_guc_submission.c > index 666dab7..fb59e44 100644 > --- a/drivers/gpu/drm/i915/i915_guc_submission.c > +++ b/drivers/gpu/drm/i915/i915_guc_submission.c > @@ -1570,7 +1570,7 @@ int intel_guc_suspend(struct drm_device *dev) > struct i915_gem_context *ctx; > u32 data[3]; > > - if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS) > + if (guc->guc_fw.load_status != UC_FIRMWARE_SUCCESS) > return 0; > > gen9_disable_guc_interrupts(dev_priv); > @@ -1598,7 +1598,7 @@ int intel_guc_resume(struct drm_device *dev) > struct i915_gem_context *ctx; > u32 data[3]; > > - if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS) > + if (guc->guc_fw.
Re: [Intel-gfx] [PATCH 6/8] drm/i915/huc: Update SKL and BXT HuC Loading Support
On Wed, Nov 09, 2016 at 10:51:35AM -0800, Anusha Srivatsa wrote: > From: Peter Antoine > > This patch adds the HuC Loading for the BXT. > Version 1.7 of the HuC firmware. > > It also updates the file construction and specifying the > required version similar to that of GuC for both SKL and BXT. > Add an extra field for the build number. Adopted the approach used in- > https://patchwork.freedesktop.org/patch/104355/ > The improved file construction should be rolled in as a revision to patch 3 as we discussed. It is bad form to submit a patch set where a later patch is fixing an issue in an earlier patch. Just fix the original patch. -Jeff > v2: rebased. > v3: rebased. > changed file name to match the install package format. > v7: rebased. > v8: rebased. > v10: rebased. > > Cc: Tvrtko Ursulin > Cc: Jeff Mcgee > Signed-off-by: Anusha Srivatsa > Signed-off-by: Peter Antoine > Reviewed-by: David Gordon > --- > drivers/gpu/drm/i915/intel_huc_loader.c | 26 +++--- > 1 file changed, 23 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c > b/drivers/gpu/drm/i915/intel_huc_loader.c > index dcd9970..9a93adb 100644 > --- a/drivers/gpu/drm/i915/intel_huc_loader.c > +++ b/drivers/gpu/drm/i915/intel_huc_loader.c > @@ -39,10 +39,26 @@ > * > * Note that HuC firmware loading must be done before GuC loading. > */ > +#define SKL_FW_MAJOR 01 > +#define SKL_FW_MINOR 07 > +#define SKL_BLD_NUM 1398 > > -#define I915_SKL_HUC_UCODE "i915/skl_huc_ver01_07_1398.bin" > +#define BXT_FW_MAJOR 01 > +#define BXT_FW_MINOR 07 > +#define BXT_BLD_NUM 1398 > + > +#define HUC_FW_PATH(platform, major, minor, bld_num) \ > + "i915/" __stringify(platform) "_huc_ver" __stringify(major) "_" \ > + __stringify(minor) "_" __stringify(bld_num) ".bin" > + > +#define I915_SKL_HUC_UCODE HUC_FW_PATH(skl, SKL_FW_MAJOR, \ > + SKL_FW_MINOR, SKL_BLD_NUM) > MODULE_FIRMWARE(I915_SKL_HUC_UCODE); > > +#define I915_BXT_HUC_UCODE HUC_FW_PATH(bxt, BXT_FW_MAJOR, \ > + BXT_FW_MINOR, BXT_BLD_NUM) > +MODULE_FIRMWARE(I915_BXT_HUC_UCODE); > + > /** > * huc_ucode_xfer() - DMA's the firmware > * @dev_priv: the drm device > @@ -148,8 +164,12 @@ void intel_huc_init(struct drm_device *dev) > > if (IS_SKYLAKE(dev_priv)) { > fw_path = I915_SKL_HUC_UCODE; > - huc_fw->major_ver_wanted = 1; > - huc_fw->minor_ver_wanted = 7; > + huc_fw->major_ver_wanted = SKL_FW_MAJOR; > + huc_fw->minor_ver_wanted = SKL_FW_MINOR; > + } else if (IS_BROXTON(dev_priv)) { > + fw_path = I915_BXT_HUC_UCODE; > + huc_fw->major_ver_wanted = BXT_FW_MAJOR; > + huc_fw->minor_ver_wanted = BXT_FW_MINOR; > } > > if (fw_path == NULL) > -- > 2.7.4 > ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915/huc: Update the construction of file path for HuC similar to that of GuC
On Mon, Oct 31, 2016 at 03:24:53PM -0700, Anusha Srivatsa wrote: > Update the file construction and specifying the required version > similar to that of GuC.Add an extra field for the build number. > Adopted the approach used in > https://patchwork.freedesktop.org/patch/104355/ > > Cc: Jeff Mcgee > Signed-off-by: Anusha Srivatsa > --- > drivers/gpu/drm/i915/intel_huc_loader.c | 25 +++-- > 1 file changed, 19 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c > b/drivers/gpu/drm/i915/intel_huc_loader.c > index 2f5d9d9..419caae 100644 > --- a/drivers/gpu/drm/i915/intel_huc_loader.c > +++ b/drivers/gpu/drm/i915/intel_huc_loader.c > @@ -39,11 +39,24 @@ > * > * Note that HuC firmware loading must be done before GuC loading. > */ > +#define SKL_FW_MAJOR 01 > +#define SKL_FW_MINOR 07 > +#define SKL_BLD_NUM 1398 > > -#define I915_SKL_HUC_UCODE "i915/skl_huc_ver01_07_1398.bin" > +#define BXT_FW_MAJOR 01 > +#define BXT_FW_MINOR 07 > +#define BXT_BLD_NUM 1398 > + > +#define HUC_FW_PATH(platform, major, minor, bld_num) \ > + "i915/" __stringify(platform) "_huc_ver" __stringify(major) "_" \ > + __stringify(minor) "_" __stringify(bld_num) ".bin" > + > +#define I915_SKL_HUC_UCODE HUC_FW_PATH(skl, SKL_FW_MAJOR, \ > + SKL_FW_MINOR, SKL_BLD_NUM) > MODULE_FIRMWARE(I915_SKL_HUC_UCODE); > > -#define I915_BXT_HUC_UCODE "i915/bxt_huc_ver01_07_1398.bin" > +#define I915_BXT_HUC_UCODE HUC_FW_PATH(bxt, BXT_FW_MAJOR, \ > + BXT_FW_MINOR, BXT_BLD_NUM) > MODULE_FIRMWARE(I915_BXT_HUC_UCODE); > > /** > @@ -151,12 +164,12 @@ void intel_huc_init(struct drm_device *dev) > > if (IS_SKYLAKE(dev_priv)) { > fw_path = I915_SKL_HUC_UCODE; > - huc_fw->major_ver_wanted = 1; > - huc_fw->minor_ver_wanted = 7; > + huc_fw->major_ver_wanted = SKL_FW_MAJOR; > + huc_fw->minor_ver_wanted = SKL_FW_MINOR; > } else if (IS_BROXTON(dev_priv)) { > fw_path = I915_BXT_HUC_UCODE; > - huc_fw->major_ver_wanted = 1; > - huc_fw->minor_ver_wanted = 7; > + huc_fw->major_ver_wanted = BXT_FW_MAJOR; > + huc_fw->minor_ver_wanted = BXT_FW_MINOR; > } > > if (fw_path == NULL) > -- > 2.7.4 > Looks good but it would be far better to make these changes in the corresponding patches within the origin HuC patch set, rather than proposing a follow-up patch to correct issues in that set (which is not yet merged and can be updated). -Jeff ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] i915/GuC: Make GuC loads default
I agree that the parameter controls could use a clean-up, which could include eventual removal of the enable_guc_loading parameter. But for now loading parameter should be auto by default. Might be a good idea to temporarily set the has_guc parameter to 0 for BXT and KBL since those firmwares have not yet been made available (I don't see them on 01.org). In either case... Reviewed-by: Jeff McGee On Mon, Oct 31, 2016 at 10:06:27AM -0700, Rodrigo Vivi wrote: > Could someone please ack this? We need this before getting HuC. > > GuC submission has regressions so the submission is not getting enabled. > But we need to have GuC loaded to be able to use HuC. > > Thanks, > Rodrigo. > > On Thu, Oct 6, 2016 at 11:08 AM, Rodrigo Vivi wrote: > > I also asked that same question many times. Maybe they can be unified > > later when we enable submission by default, but right now I believe > > this is the way to go, so > > > > Reviewed-by: Rodrigo Vivi > > > > > > On Thu, Oct 6, 2016 at 11:03 AM, Srivatsa, Anusha > > wrote: > >> > >> > >>>-Original Message- > >>>From: Chris Wilson [mailto:ch...@chris-wilson.co.uk] > >>>Sent: Wednesday, October 5, 2016 11:57 PM > >>>To: Srivatsa, Anusha > >>>Cc: intel-gfx@lists.freedesktop.org > >>>Subject: Re: [Intel-gfx] [PATCH] i915/GuC: Make GuC loads default > >>> > >>>On Wed, Oct 05, 2016 at 04:20:04PM -0700, Anusha Srivatsa wrote: > >>>> Proper functioning of HuC requires GuC to be loaded. Make GuC loads > >>>> default so that HuC works seemlessly. > >>>> Also, note that GuC submission is not made default and still needs to > >>>> be given as a kernel parameter. > >>>> Once the issues around GuC submission is resolved it is intended to > >>>> make it default as well. > >>> > >>>Why is this even a separate parameter? -Chris > >> > >> It is a separate parameter because HuC requires GuC to be loaded. It is ok > >> if command submission is not happening through GuC but GuC "has to" be > >> loaded for HuC to function. Guc_submission parameter enables the command > >> submission through GUC. But, guc_loading parameter ensures not only that > >> the GuC is loaded but also that HuC can now function. > >> > >> Anusha > >>>-- > >>>Chris Wilson, Intel Open Source Technology Centre > >> ___ > >> Intel-gfx mailing list > >> Intel-gfx@lists.freedesktop.org > >> https://lists.freedesktop.org/mailman/listinfo/intel-gfx > > > > > > > > -- > > Rodrigo Vivi > > Blog: http://blog.vivi.eng.br > > > > -- > Rodrigo Vivi > Blog: http://blog.vivi.eng.br > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 7/7] drm/i915/get_params: Add HuC status to getparams
Patch set header includes links to libva intent to use the interface. Thanks Reviewed-by: Jeff McGee On Fri, Oct 28, 2016 at 05:05:46PM -0700, Anusha Srivatsa wrote: > From: Peter Antoine > > This patch will allow for getparams to return the status of the HuC. > As the HuC has to be validated by the GuC this patch uses the validated > status to show when the HuC is loaded and ready for use. You cannot use > the loaded status as with the GuC as the HuC is verified after it is > loaded and is not usable until it is verified. > > v2: removed the forewakes as the registers are already force-woken. > (T.Ursulin) > v4: rebased. > v5: rebased. > v6: rebased. > > Tested-by: Xiang Haihao > Signed-off-by: Anusha Srivatsa > Signed-off-by: Peter Antoine > Reviewed-by: Rodrigo Vivi > --- > drivers/gpu/drm/i915/i915_drv.c | 5 + > drivers/gpu/drm/i915/intel_huc.h| 1 + > drivers/gpu/drm/i915/intel_huc_loader.c | 14 ++ > include/uapi/drm/i915_drm.h | 1 + > 4 files changed, 21 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c > index 2f36672..038ed8d 100644 > --- a/drivers/gpu/drm/i915/i915_drv.c > +++ b/drivers/gpu/drm/i915/i915_drv.c > @@ -49,6 +49,8 @@ > #include "i915_trace.h" > #include "i915_vgpu.h" > #include "intel_drv.h" > +#include "intel_guc.h" > +#include "intel_huc.h" > > static struct drm_driver driver; > > @@ -346,6 +348,9 @@ static int i915_getparam(struct drm_device *dev, void > *data, >*/ > value = 1; > break; > + case I915_PARAM_HAS_HUC: > + value = intel_is_huc_valid(dev_priv); > + break; > default: > DRM_DEBUG("Unknown parameter %d\n", param->param); > return -EINVAL; > diff --git a/drivers/gpu/drm/i915/intel_huc.h > b/drivers/gpu/drm/i915/intel_huc.h > index 3ce0299..2e150be 100644 > --- a/drivers/gpu/drm/i915/intel_huc.h > +++ b/drivers/gpu/drm/i915/intel_huc.h > @@ -39,4 +39,5 @@ struct intel_huc { > void intel_huc_init(struct drm_device *dev); > void intel_huc_fini(struct drm_device *dev); > int intel_huc_load(struct drm_device *dev); > +extern int intel_is_huc_valid(struct drm_i915_private *dev_priv); > #endif > diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c > b/drivers/gpu/drm/i915/intel_huc_loader.c > index 0969bdf..2f5d9d9 100644 > --- a/drivers/gpu/drm/i915/intel_huc_loader.c > +++ b/drivers/gpu/drm/i915/intel_huc_loader.c > @@ -265,3 +265,17 @@ void intel_huc_fini(struct drm_device *dev) > > huc_fw->fetch_status = UC_FIRMWARE_NONE; > } > + > +/** > + * intel_is_huc_valid() - Check to see if the HuC is fully loaded. > + * @dev_priv:drm device to check. > + * > + * This function will return true if the guc has been loaded and > + * has valid firmware. The simplest way of doing this is to check > + * if the HuC has been validated, if so it must have been loaded. > + */ > +int intel_is_huc_valid(struct drm_i915_private *dev_priv) > +{ > + return ((I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED) != 0); > +} > + > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h > index 03725fe..aa7667e 100644 > --- a/include/uapi/drm/i915_drm.h > +++ b/include/uapi/drm/i915_drm.h > @@ -388,6 +388,7 @@ typedef struct drm_i915_irq_wait { > #define I915_PARAM_HAS_POOLED_EU 38 > #define I915_PARAM_MIN_EU_IN_POOL 39 > #define I915_PARAM_MMAP_GTT_VERSION 40 > +#define I915_PARAM_HAS_HUC42 > > typedef struct drm_i915_getparam { > __s32 param; > -- > 2.7.4 > > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 6/7] drm/i915/huc: Add BXT HuC Loading Support
On Fri, Oct 28, 2016 at 05:05:45PM -0700, Anusha Srivatsa wrote: > From: Peter Antoine > > This patch adds the HuC Loading for the BXT. > Version 1.7 of the HuC firmware. > > v2: rebased. > v3: rebased. > changed file name to match the install package format. > v7: rebased. > v8: rebased. > > Signed-off-by: Anusha Srivatsa > Signed-off-by: Peter Antoine > Reviewed-by: David Gordon > --- > drivers/gpu/drm/i915/intel_huc_loader.c | 7 +++ > 1 file changed, 7 insertions(+) > > diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c > b/drivers/gpu/drm/i915/intel_huc_loader.c > index dcd9970..0969bdf 100644 > --- a/drivers/gpu/drm/i915/intel_huc_loader.c > +++ b/drivers/gpu/drm/i915/intel_huc_loader.c > @@ -43,6 +43,9 @@ > #define I915_SKL_HUC_UCODE "i915/skl_huc_ver01_07_1398.bin" > MODULE_FIRMWARE(I915_SKL_HUC_UCODE); > > +#define I915_BXT_HUC_UCODE "i915/bxt_huc_ver01_07_1398.bin" > +MODULE_FIRMWARE(I915_BXT_HUC_UCODE); > + This will need updating if the newer firmware version/name macros in intel_guc_loader.c are adopted. -Jeff > /** > * huc_ucode_xfer() - DMA's the firmware > * @dev_priv: the drm device > @@ -150,6 +153,10 @@ void intel_huc_init(struct drm_device *dev) > fw_path = I915_SKL_HUC_UCODE; > huc_fw->major_ver_wanted = 1; > huc_fw->minor_ver_wanted = 7; > + } else if (IS_BROXTON(dev_priv)) { > + fw_path = I915_BXT_HUC_UCODE; > + huc_fw->major_ver_wanted = 1; > + huc_fw->minor_ver_wanted = 7; Use version macros here when that part is ready. -Jeff > } > > if (fw_path == NULL) > -- > 2.7.4 > > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 5/7] drm/i915/huc: Support HuC authentication
Reviewed-by: Jeff McGee On Fri, Oct 28, 2016 at 05:05:44PM -0700, Anusha Srivatsa wrote: > From: Peter Antoine > > The HuC authentication is done by host2guc call. The HuC RSA keys > are sent to GuC for authentication. > > v2: rebased on top of drm-intel-nightly. > changed name format and upped version 1.7. > v3: rebased on top of drm-intel-nightly. > v4: changed wait_for_automic to wait_for > v5: rebased. > v7: rebased. > v8: rebased. > v9: rebased. Rename intel_huc_auh() to intel_guc_auth_huc() > and place the prototype in intel_guc.h,correct the comments. > > Tested-by: Xiang Haihao > Signed-off-by: Anusha Srivatsa > Signed-off-by: Alex Dai > Signed-off-by: Peter Antoine > Reviewed-by: Dave Gordon > --- > drivers/gpu/drm/i915/i915_guc_submission.c | 63 > ++ > drivers/gpu/drm/i915/intel_guc.h | 2 +- > drivers/gpu/drm/i915/intel_guc_fwif.h | 1 + > drivers/gpu/drm/i915/intel_guc_loader.c| 2 + > 4 files changed, 67 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c > b/drivers/gpu/drm/i915/i915_guc_submission.c > index 99dc5d9..936eefc 100644 > --- a/drivers/gpu/drm/i915/i915_guc_submission.c > +++ b/drivers/gpu/drm/i915/i915_guc_submission.c > @@ -27,6 +27,7 @@ > #include > #include "i915_drv.h" > #include "intel_guc.h" > +#include "intel_huc.h" > > /** > * DOC: GuC-based command submission > @@ -1713,3 +1714,65 @@ int i915_guc_log_control(struct drm_i915_private > *dev_priv, u64 control_val) > > return ret; > } > + > +/** > + * intel_guc_auth_huc() - authenticate ucode > + * @dev: the drm device > + * > + * Triggers a HuC fw authentication request to the GuC via host-2-guc > + * interface. > + */ > +void intel_guc_auth_huc(struct drm_device *dev) > +{ > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct intel_guc *guc = &dev_priv->guc; > + struct intel_huc *huc = &dev_priv->huc; > + struct i915_vma *vma; > + int ret; > + u32 data[2]; > + > + /* Bypass the case where there is no HuC firmware */ > + if (huc->huc_fw.fetch_status == UC_FIRMWARE_NONE || > + huc->huc_fw.load_status == UC_FIRMWARE_NONE) > + return; > + > + if (guc->guc_fw.load_status != UC_FIRMWARE_SUCCESS) { > + DRM_ERROR("HuC: GuC fw wasn't loaded. Can't authenticate"); > + return; > + } > + > + if (huc->huc_fw.load_status != UC_FIRMWARE_SUCCESS) { > + DRM_ERROR("HuC: fw wasn't loaded. Nothing to authenticate"); > + return; > + } > + > + vma = i915_gem_object_ggtt_pin(huc->huc_fw.uc_fw_obj, NULL, 0, 0, 0); > + if (IS_ERR(vma)) { > + DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma)); > + return; > + } > + > + > + /* Invalidate GuC TLB to let GuC take the latest updates to GTT. */ > + I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE); > + > + /* Specify auth action and where public signature is. */ > + data[0] = HOST2GUC_ACTION_AUTHENTICATE_HUC; > + data[1] = i915_ggtt_offset(vma) + huc->huc_fw.rsa_offset; > + > + ret = host2guc_action(guc, data, ARRAY_SIZE(data)); > + if (ret) { > + DRM_ERROR("HuC: GuC did not ack Auth request\n"); > + goto out; > + } > + > + /* Check authentication status, it should be done by now */ > + ret = wait_for((I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED) > 0, 50); > + if (ret) { > + DRM_ERROR("HuC: Authentication failed\n"); > + goto out; > + } > + > +out: > + i915_vma_unpin(vma); > +} > diff --git a/drivers/gpu/drm/i915/intel_guc.h > b/drivers/gpu/drm/i915/intel_guc.h > index 4647e41..ffdd5b9 100644 > --- a/drivers/gpu/drm/i915/intel_guc.h > +++ b/drivers/gpu/drm/i915/intel_guc.h > @@ -197,5 +197,5 @@ void i915_guc_flush_logs(struct drm_i915_private > *dev_priv); > void i915_guc_register(struct drm_i915_private *dev_priv); > void i915_guc_unregister(struct drm_i915_private *dev_priv); > int i915_guc_log_control(struct drm_i915_private *dev_priv, u64 control_val); > - > +void intel_guc_auth_huc(struct drm_device *dev); > #endif > diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h > b/drivers/gpu/drm/i915/intel_guc_fwif.h > index c2a7fdd..99a092d 100644 > --- a/drivers/gpu/drm/i915/intel_guc_fwif.h > +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h > @@ -513,6 +513,7 @@ enum host2guc_action { > HOST
Re: [Intel-gfx] [PATCH 3/7] drm/i915/huc: Add HuC fw loading support
On Fri, Oct 28, 2016 at 05:05:42PM -0700, Anusha Srivatsa wrote: > From: Peter Antoine > > The HuC loading process is similar to GuC. The intel_uc_fw_fetch() > is used for both cases. > > HuC loading needs to be before GuC loading. The WOPCM setting must > be done early before loading any of them. > > v2: rebased on-top of drm-intel-nightly. > removed if(HAS_GUC()) before the guc call. (D.Gordon) > update huc_version number of format. > v3: rebased to drm-intel-nightly, changed the file name format to > match the one in the huc package. > Changed dev->dev_private to to_i915() > v4: moved function back to where it was. > change wait_for_atomic to wait_for. > v5: rebased + comment changes. > v7: rebased. > v8: rebased. > v9: rebased. Changed the year in the copyright message to reflect > the right year.Correct the comments,remove the unwanted WARN message, > replace drm_gem_object_unreference() with i915_gem_object_put().Make the > prototypes in intel_huc.h non-extern. > > Tested-by: Xiang Haihao > Signed-off-by: Anusha Srivatsa > Signed-off-by: Alex Dai > Signed-off-by: Peter Antoine > Reviewed-by: Dave Gordon > --- > drivers/gpu/drm/i915/Makefile | 1 + > drivers/gpu/drm/i915/i915_drv.c | 3 + > drivers/gpu/drm/i915/i915_drv.h | 3 + > drivers/gpu/drm/i915/i915_guc_reg.h | 3 + > drivers/gpu/drm/i915/intel_guc.h| 1 + > drivers/gpu/drm/i915/intel_guc_loader.c | 6 +- > drivers/gpu/drm/i915/intel_huc.h| 42 ++ > drivers/gpu/drm/i915/intel_huc_loader.c | 260 > > 8 files changed, 317 insertions(+), 2 deletions(-) > create mode 100644 drivers/gpu/drm/i915/intel_huc.h > create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > index 6123400..0528168 100644 > --- a/drivers/gpu/drm/i915/Makefile > +++ b/drivers/gpu/drm/i915/Makefile > @@ -52,6 +52,7 @@ i915-y += i915_cmd_parser.o \ > > # general-purpose microcontroller (GuC) support > i915-y += intel_guc_loader.o \ > + intel_huc_loader.o \ > i915_guc_submission.o > > # autogenerated null render state > diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c > index af3559d..2f36672 100644 > --- a/drivers/gpu/drm/i915/i915_drv.c > +++ b/drivers/gpu/drm/i915/i915_drv.c > @@ -594,6 +594,7 @@ static int i915_load_modeset_init(struct drm_device *dev) >* working irqs for e.g. gmbus and dp aux transfers. */ > intel_modeset_init(dev); > > + intel_huc_init(dev); > intel_guc_init(dev); > > ret = i915_gem_init(dev); > @@ -621,6 +622,7 @@ static int i915_load_modeset_init(struct drm_device *dev) > DRM_ERROR("failed to idle hardware; continuing to unload!\n"); > i915_gem_fini(dev); > cleanup_irq: > + intel_huc_fini(dev); > intel_guc_fini(dev); > drm_irq_uninstall(dev); > intel_teardown_gmbus(dev); > @@ -1304,6 +1306,7 @@ void i915_driver_unload(struct drm_device *dev) > /* Flush any outstanding unpin_work. */ > drain_workqueue(dev_priv->wq); > > + intel_huc_fini(dev); > intel_guc_fini(dev); > i915_gem_fini(dev); > intel_fbc_cleanup_cfb(dev_priv); > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index 55afb66..b0376f0 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -55,6 +55,7 @@ > #include "intel_bios.h" > #include "intel_dpll_mgr.h" > #include "intel_guc.h" > +#include "intel_huc.h" > #include "intel_lrc.h" > #include "intel_ringbuffer.h" > > @@ -1786,6 +1787,7 @@ struct drm_i915_private { > > struct intel_gvt *gvt; > > + struct intel_huc huc; > struct intel_guc guc; > > struct intel_csr csr; > @@ -2837,6 +2839,7 @@ struct drm_i915_cmd_table { > #define HAS_GUC(dev) (INTEL_INFO(dev)->has_guc) > #define HAS_GUC_UCODE(dev) (HAS_GUC(dev)) > #define HAS_GUC_SCHED(dev) (HAS_GUC(dev)) > +#define HAS_HUC_UCODE(dev) (HAS_GUC(dev)) > > #define HAS_RESOURCE_STREAMER(dev) (INTEL_INFO(dev)->has_resource_streamer) > > diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h > b/drivers/gpu/drm/i915/i915_guc_reg.h > index a47e1e4..64e942a 100644 > --- a/drivers/gpu/drm/i915/i915_guc_reg.h > +++ b/drivers/gpu/drm/i915/i915_guc_reg.h > @@ -61,9 +61,12 @@ > #define DMA_ADDRESS_SPACE_GTT(8 << 16) > #define DMA_COPY_SIZE_MMIO(0xc310) > #define DMA_CTRL _MMIO(0xc314) > +#define HUC_UKERNEL (1<<9) > #define UOS_MOVE (1<<4) > #define START_DMA(1<<0) > #define DMA_GUC_WOPCM_OFFSET _MMIO(0xc340) > +#define HUC_LOADING_AGENT_VCR(0<<1) > +#define HUC_LOADING_AGENT_GUC(1<<1) > #define GUC_WOPCM_OFFSET_VALUE 0x8 /*
Re: [Intel-gfx] [PATCH 2/7] drm/i915/huc: Unified css_header struct for GuC and HuC
Reviewed-by: Jeff McGee On Fri, Oct 28, 2016 at 05:05:41PM -0700, Anusha Srivatsa wrote: > From: Peter Antoine > > HuC firmware css header has almost exactly same definition as GuC > firmware except for the sw_version. Also, add a new member fw_type > into intel_uc_fw to indicate what kind of fw it is. So, the loader > will pull right sw_version from header. > > v2: rebased on-top of drm-intel-nightly > v3: rebased on-top of drm-intel-nightly (again). > v4: rebased + spaces. > v7: rebased. > v8: rebased. > v9: rebased. Rename device_id to guc_branch_client_version, > make guc_sw_version a union. . Put UC_FW_TYPE_GUC > and UC_FW_TYPE_HUC into an enum. > > Tested-by: Xiang Haihao > Signed-off-by: Anusha Srivatsa > Signed-off-by: Alex Dai > Signed-off-by: Peter Antoine > Reviewed-by: Dave Gordon > --- > drivers/gpu/drm/i915/intel_guc.h| 6 + > drivers/gpu/drm/i915/intel_guc_fwif.h | 21 + > drivers/gpu/drm/i915/intel_guc_loader.c | 41 > ++--- > 3 files changed, 51 insertions(+), 17 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_guc.h > b/drivers/gpu/drm/i915/intel_guc.h > index 186efa7..84ef2bf 100644 > --- a/drivers/gpu/drm/i915/intel_guc.h > +++ b/drivers/gpu/drm/i915/intel_guc.h > @@ -98,6 +98,11 @@ enum intel_uc_fw_status { > UC_FIRMWARE_SUCCESS > }; > > +enum { > + UC_FW_TYPE_GUC, > + UC_FW_TYPE_HUC > +}; > + > /* > * This structure encapsulates all the data needed during the process > * of fetching, caching, and loading the firmware image into the GuC. > @@ -115,6 +120,7 @@ struct intel_uc_fw { > uint16_t major_ver_found; > uint16_t minor_ver_found; > > + uint32_t fw_type; > uint32_t header_size; > uint32_t header_offset; > uint32_t rsa_size; > diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h > b/drivers/gpu/drm/i915/intel_guc_fwif.h > index 324ea90..c2a7fdd 100644 > --- a/drivers/gpu/drm/i915/intel_guc_fwif.h > +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h > @@ -154,7 +154,7 @@ > * The GuC firmware layout looks like this: > * > * +---+ > - * |guc_css_header | > + * | uc_css_header | > * | | > * | contains major/minor version | > * +---+ > @@ -181,9 +181,16 @@ > * 3. Length info of each component can be found in header, in dwords. > * 4. Modulus and exponent key are not required by driver. They may not > appear > *in fw. So driver will load a truncated firmware in this case. > + * > + * HuC firmware layout is same as GuC firmware. > + * > + * HuC firmware css header is different. However, the only difference is > where > + * the version information is saved. The uc_css_header is unified to support > + * both. Driver should get HuC version from uc_css_header.huc_sw_version, > while > + * uc_css_header.guc_sw_version for GuC. > */ > > -struct guc_css_header { > +struct uc_css_header { > uint32_t module_type; > /* header_size includes all non-uCode bits, including css_header, rsa >* key, modulus key and exponent data. */ > @@ -214,8 +221,14 @@ struct guc_css_header { > > char username[8]; > char buildnumber[12]; > - uint32_t device_id; > - uint32_t guc_sw_version; > + union { > + uint32_t guc_branch_client_version; > + uint32_t huc_sw_version; > + }; > + union { > + uint32_t guc_sw_version; > + uint32_t huc_reserved; > + }; > uint32_t prod_preprod_fw; > uint32_t reserved[12]; > uint32_t header_info; > diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c > b/drivers/gpu/drm/i915/intel_guc_loader.c > index 6683a88..ff26d2c 100644 > --- a/drivers/gpu/drm/i915/intel_guc_loader.c > +++ b/drivers/gpu/drm/i915/intel_guc_loader.c > @@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct > intel_uc_fw *uc_fw) > struct pci_dev *pdev = dev->pdev; > struct drm_i915_gem_object *obj; > const struct firmware *fw; > - struct guc_css_header *css; > + struct uc_css_header *css; > size_t size; > int err; > > @@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct > intel_uc_fw *uc_fw) > uc_fw->uc_fw_path, fw); > > /* Check the size of the blob before examining buffer contents */ > - if (fw->size < sizeof(struct guc_css_header)) { > + if (fw->size < sizeof(struct uc_css_header)) { &
Re: [Intel-gfx] [PATCH 3/8] drm/i915/huc: Add HuC fw loading support
On Mon, Oct 24, 2016 at 02:24:01PM -0700, Carlos Santa wrote: > On Thu, 2016-10-13 at 13:54 -0700, Jeff McGee wrote: > > On Thu, Oct 13, 2016 at 10:42:42AM -0700, Jeff McGee wrote: > > > > > > On Mon, Oct 03, 2016 at 11:42:57AM -0700, Anusha Srivatsa wrote: > > > > > > > > From: Peter Antoine > > > > > > > > The HuC loading process is similar to GuC. The > > > > intel_uc_fw_fetch() > > > > is used for both cases. > > > > > > > > HuC loading needs to be before GuC loading. The WOPCM setting > > > > must > > > > be done early before loading any of them. > > > > > > > > v2: rebased on-top of drm-intel-nightly. > > > > removed if(HAS_GUC()) before the guc call. (D.Gordon) > > > > update huc_version number of format. > > > > v3: rebased to drm-intel-nightly, changed the file name format to > > > > match the one in the huc package. > > > > Changed dev->dev_private to to_i915() > > > > v4: moved function back to where it was. > > > > change wait_for_atomic to wait_for. > > > > v5: rebased + comment changes. > > > > v7: rebased. > > > > v8: rebased. > > > > > > > > Tested-by: Xiang Haihao > > > > Signed-off-by: Anusha Srivatsa > > > > Signed-off-by: Alex Dai > > > > Signed-off-by: Peter Antoine > > > > Reviewed-by: Dave Gordon > > > > --- > > > > drivers/gpu/drm/i915/Makefile | 1 + > > > > drivers/gpu/drm/i915/i915_drv.c | 3 + > > > > drivers/gpu/drm/i915/i915_drv.h | 3 + > > > > drivers/gpu/drm/i915/i915_guc_reg.h | 3 + > > > > drivers/gpu/drm/i915/intel_guc.h| 1 + > > > > drivers/gpu/drm/i915/intel_guc_loader.c | 6 +- > > > > drivers/gpu/drm/i915/intel_huc.h| 44 ++ > > > > drivers/gpu/drm/i915/intel_huc_loader.c | 268 > > > > > > > > 8 files changed, 327 insertions(+), 2 deletions(-) > > > > create mode 100644 drivers/gpu/drm/i915/intel_huc.h > > > > create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c > > > > > > > > diff --git a/drivers/gpu/drm/i915/Makefile > > > > b/drivers/gpu/drm/i915/Makefile > > > > index e6fe004..6e99c51 100644 > > > > --- a/drivers/gpu/drm/i915/Makefile > > > > +++ b/drivers/gpu/drm/i915/Makefile > > > > @@ -53,6 +53,7 @@ i915-y += i915_cmd_parser.o \ > > > > > > > > # general-purpose microcontroller (GuC) support > > > > i915-y += intel_guc_loader.o \ > > > > + intel_huc_loader.o \ > > > > i915_guc_submission.o > > > > > > > > # autogenerated null render state > > > > diff --git a/drivers/gpu/drm/i915/i915_drv.c > > > > b/drivers/gpu/drm/i915/i915_drv.c > > > > index 31b2b63..7af7bd6 100644 > > > > --- a/drivers/gpu/drm/i915/i915_drv.c > > > > +++ b/drivers/gpu/drm/i915/i915_drv.c > > > > @@ -613,6 +613,7 @@ static int i915_load_modeset_init(struct > > > > drm_device *dev) > > > > * working irqs for e.g. gmbus and dp aux transfers. */ > > > > intel_modeset_init(dev); > > > > > > > > + intel_huc_init(dev); > > > > intel_guc_init(dev); > > > > > > > > ret = i915_gem_init(dev); > > > > @@ -638,6 +639,7 @@ static int i915_load_modeset_init(struct > > > > drm_device *dev) > > > > cleanup_gem: > > > > i915_gem_fini(dev); > > > > cleanup_irq: > > > > + intel_huc_fini(dev); > > > > intel_guc_fini(dev); > > > > drm_irq_uninstall(dev); > > > > intel_teardown_gmbus(dev); > > > > @@ -1315,6 +1317,7 @@ void i915_driver_unload(struct drm_device > > > > *dev) > > > > /* Flush any outstanding unpin_work. */ > > > > drain_workqueue(dev_priv->wq); > > > > > > > > + intel_huc_fini(dev); > > > > intel_guc_fini(dev); > > > > i915_gem_fini(dev); > > > > intel_fbc_cleanup_cfb(dev_priv); > > > > diff --git a/drivers/gpu/drm/i915/i915_drv.h > > > > b/drivers/gpu/drm/i915/i915_drv.h > > > > index e0cb71c..625aa92 10
Re: [Intel-gfx] [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
On Thu, Oct 13, 2016 at 08:45:45AM -0700, Jeff McGee wrote: > On Mon, Oct 03, 2016 at 11:42:56AM -0700, Anusha Srivatsa wrote: > > From: Peter Antoine > > > > HuC firmware css header has almost exactly same definition as GuC > > firmware except for the sw_version. Also, add a new member fw_type > > into intel_uc_fw to indicate what kind of fw it is. So, the loader > > will pull right sw_version from header. > > > > v2: rebased on-top of drm-intel-nightly > > v3: rebased on-top of drm-intel-nightly (again). > > v4: rebased + spaces. > > v7: rebased. > > v8: rebased. > > > > Tested-by: Xiang Haihao > > Signed-off-by: Anusha Srivatsa > > Signed-off-by: Alex Dai > > Signed-off-by: Peter Antoine > > Reviewed-by: Dave Gordon > > --- > > drivers/gpu/drm/i915/intel_guc.h| 4 > > drivers/gpu/drm/i915/intel_guc_fwif.h | 16 ++--- > > drivers/gpu/drm/i915/intel_guc_loader.c | 41 > > ++--- > > 3 files changed, 45 insertions(+), 16 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/intel_guc.h > > b/drivers/gpu/drm/i915/intel_guc.h > > index b134a41..812e4ca 100644 > > --- a/drivers/gpu/drm/i915/intel_guc.h > > +++ b/drivers/gpu/drm/i915/intel_guc.h > > @@ -98,6 +98,9 @@ enum intel_uc_fw_status { > > UC_FIRMWARE_SUCCESS > > }; > > > > +#define UC_FW_TYPE_GUC 0 > > +#define UC_FW_TYPE_HUC 1 > > + > > /* > > * This structure encapsulates all the data needed during the process > > * of fetching, caching, and loading the firmware image into the GuC. > > @@ -115,6 +118,7 @@ struct intel_uc_fw { > > uint16_t major_ver_found; > > uint16_t minor_ver_found; > > > > + uint32_t fw_type; > > uint32_t header_size; > > uint32_t header_offset; > > uint32_t rsa_size; > > diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h > > b/drivers/gpu/drm/i915/intel_guc_fwif.h > > index e40db2d..b38b6b4 100644 > > --- a/drivers/gpu/drm/i915/intel_guc_fwif.h > > +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h > > @@ -154,7 +154,7 @@ > > * The GuC firmware layout looks like this: > > * > > * +---+ > > - * |guc_css_header | > > + * | uc_css_header | > > * | | > > * | contains major/minor version | > > * +---+ > > @@ -181,9 +181,16 @@ > > * 3. Length info of each component can be found in header, in dwords. > > * 4. Modulus and exponent key are not required by driver. They may not > > appear > > *in fw. So driver will load a truncated firmware in this case. > > + * > > + * HuC firmware layout is same as GuC firmware. > > + * > > + * HuC firmware css header is different. However, the only difference is > > where > > + * the version information is saved. The uc_css_header is unified to > > support > > + * both. Driver should get HuC version from uc_css_header.huc_sw_version, > > while > > + * uc_css_header.guc_sw_version for GuC. > > */ > > > > -struct guc_css_header { > > +struct uc_css_header { > > uint32_t module_type; > > /* header_size includes all non-uCode bits, including css_header, rsa > > * key, modulus key and exponent data. */ > > @@ -214,7 +221,10 @@ struct guc_css_header { > > > > char username[8]; > > char buildnumber[12]; > > - uint32_t device_id; > > + union { > > + uint32_t device_id; > > + uint32_t huc_sw_version; > > + }; > > uint32_t guc_sw_version; > > uint32_t prod_preprod_fw; > > uint32_t reserved[12]; > > I propose renaming the device_id field in this union to > 'guc_client_branch_version'. GuC uses this position to store a client > version and branch version. I'm not sure where the 'device_id' term came > from. We don't reference this currently but may need to in the future > so might as well name it properly. At the very least we should probably > make it guc_device_id, to help indicate that it applies to guc fw only. > > In that same vein, can we make guc_sw_version into a union as below to > reinforce the difference to huc? > > union { > uint32_t guc_sw_version; > uint32_t huc_reserved; > }; > > Jeff > One correction. The branch version is considered the "major&qu
Re: [Intel-gfx] [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams
On Mon, Oct 03, 2016 at 11:43:02AM -0700, Anusha Srivatsa wrote: > From: Peter Antoine > > This patch will allow for getparams to return the status of the HuC. > As the HuC has to be validated by the GuC this patch uses the validated > status to show when the HuC is loaded and ready for use. You cannot use > the loaded status as with the GuC as the HuC is verified after it is > loaded and is not usable until it is verified. > > v2: removed the forewakes as the registers are already force-woken. > (T.Ursulin) > v4: rebased. > v5: rebased. > > Tested-by: Xiang Haihao > Signed-off-by: Anusha Srivatsa > Signed-off-by: Peter Antoine > --- > drivers/gpu/drm/i915/i915_drv.c | 4 > drivers/gpu/drm/i915/intel_huc.h| 2 +- > drivers/gpu/drm/i915/intel_huc_loader.c | 14 ++ > include/uapi/drm/i915_drm.h | 1 + > 4 files changed, 20 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c > index ff1c18d..0d7b290 100644 > --- a/drivers/gpu/drm/i915/i915_drv.c > +++ b/drivers/gpu/drm/i915/i915_drv.c > @@ -49,6 +49,7 @@ > #include "i915_trace.h" > #include "i915_vgpu.h" > #include "intel_drv.h" > +#include "intel_huc.h" > #include "intel_guc.h" > > static struct drm_driver driver; > @@ -343,6 +344,9 @@ static int i915_getparam(struct drm_device *dev, void > *data, > case I915_PARAM_HAS_GUC: > value = intel_is_guc_valid(dev_priv); > break; > + case I915_PARAM_HAS_HUC: > + value = intel_is_huc_valid(dev_priv); > + break; > default: > DRM_DEBUG("Unknown parameter %d\n", param->param); > return -EINVAL; > diff --git a/drivers/gpu/drm/i915/intel_huc.h > b/drivers/gpu/drm/i915/intel_huc.h > index 946caa7..5eac625 100644 > --- a/drivers/gpu/drm/i915/intel_huc.h > +++ b/drivers/gpu/drm/i915/intel_huc.h > @@ -40,5 +40,5 @@ extern void intel_huc_init(struct drm_device *dev); > extern int intel_huc_load(struct drm_device *dev); > extern void intel_huc_auth(struct drm_device *dev); > extern void intel_huc_fini(struct drm_device *dev); > - > +extern int intel_is_huc_valid(struct drm_i915_private *dev_priv); > #endif > diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c > b/drivers/gpu/drm/i915/intel_huc_loader.c > index 87a6948..d574183 100644 > --- a/drivers/gpu/drm/i915/intel_huc_loader.c > +++ b/drivers/gpu/drm/i915/intel_huc_loader.c > @@ -273,3 +273,17 @@ void intel_huc_fini(struct drm_device *dev) > > huc_fw->fetch_status = UC_FIRMWARE_NONE; > } > + > +/** > + * intel_is_huc_valid() - Check to see if the HuC is fully loaded. > + * @dev_priv:drm device to check. > + * > + * This function will return true if the guc has been loaded and > + * has valid firmware. The simplest way of doing this is to check > + * if the HuC has been validated, if so it must have been loaded. > + */ > +int intel_is_huc_valid(struct drm_i915_private *dev_priv) I'm still unclear on the 'intel' vs. 'i915' prefix usage. But it seems that intel prefixed functions accept drm_device instead of drm_i915_private. Also, need to see the userspace usage of this new GETPARAM. > +{ > + return ((I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED) != 0); > +} > + > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h > index 629fb5e..d236520 100644 > --- a/include/uapi/drm/i915_drm.h > +++ b/include/uapi/drm/i915_drm.h > @@ -389,6 +389,7 @@ typedef struct drm_i915_irq_wait { > #define I915_PARAM_MIN_EU_IN_POOL 39 > #define I915_PARAM_MMAP_GTT_VERSION 40 > #define I915_PARAM_HAS_GUC41 > +#define I915_PARAM_HAS_HUC42 > > typedef struct drm_i915_getparam { > __s32 param; > -- > 2.7.4 > > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 7/8] drm/i915/get_params: Add GuC status to getparams
On Fri, Oct 07, 2016 at 09:11:03AM +0200, Daniel Vetter wrote: > On Wed, Oct 05, 2016 at 01:51:14PM -0700, Rodrigo Vivi wrote: > > > > > > Reviewed-by: Rodrigo Vivi > > This is new uabi. Where's the userspace? > > Checking this is part of the review. > -Daniel > I'm not sure that GuC status is strictly needed by userspace. No direct dependencies that I am aware of. HuC status is needed and that is the subsequent patch. -Jeff > > > > On Mon, Oct 03, 2016 at 11:43:01AM -0700, Anusha Srivatsa wrote: > > > From: Peter Antoine > > > > > > This patch returns the GuC status to the caller. It is used so > > > that the userspace knows if the GuC has been loaded. > > > > > > v4: rebase. > > > v5: rebased. > > > > > > Signed-off-by: Anusha Srivatsa > > > Signed-off-by: Peter Antoine > > > --- > > > drivers/gpu/drm/i915/i915_drv.c | 4 > > > drivers/gpu/drm/i915/intel_guc.h| 2 +- > > > drivers/gpu/drm/i915/intel_guc_loader.c | 18 ++ > > > include/uapi/drm/i915_drm.h | 1 + > > > 4 files changed, 24 insertions(+), 1 deletion(-) > > > > > > diff --git a/drivers/gpu/drm/i915/i915_drv.c > > > b/drivers/gpu/drm/i915/i915_drv.c > > > index 7af7bd6..ff1c18d 100644 > > > --- a/drivers/gpu/drm/i915/i915_drv.c > > > +++ b/drivers/gpu/drm/i915/i915_drv.c > > > @@ -49,6 +49,7 @@ > > > #include "i915_trace.h" > > > #include "i915_vgpu.h" > > > #include "intel_drv.h" > > > +#include "intel_guc.h" > > > > > > static struct drm_driver driver; > > > > > > @@ -339,6 +340,9 @@ static int i915_getparam(struct drm_device *dev, void > > > *data, > > >*/ > > > value = 1; > > > break; > > > + case I915_PARAM_HAS_GUC: > > > + value = intel_is_guc_valid(dev_priv); > > > + break; > > > default: > > > DRM_DEBUG("Unknown parameter %d\n", param->param); > > > return -EINVAL; > > > diff --git a/drivers/gpu/drm/i915/intel_guc.h > > > b/drivers/gpu/drm/i915/intel_guc.h > > > index af76ffe..3a7fa7e 100644 > > > --- a/drivers/gpu/drm/i915/intel_guc.h > > > +++ b/drivers/gpu/drm/i915/intel_guc.h > > > @@ -168,5 +168,5 @@ int i915_guc_submission_enable(struct > > > drm_i915_private *dev_priv); > > > int i915_guc_wq_reserve(struct drm_i915_gem_request *rq); > > > void i915_guc_submission_disable(struct drm_i915_private *dev_priv); > > > void i915_guc_submission_fini(struct drm_i915_private *dev_priv); > > > - > > > +int intel_is_guc_valid(struct drm_i915_private *dev_priv); > > > #endif > > > diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c > > > b/drivers/gpu/drm/i915/intel_guc_loader.c > > > index 31a2b0a..5d2a703 100644 > > > --- a/drivers/gpu/drm/i915/intel_guc_loader.c > > > +++ b/drivers/gpu/drm/i915/intel_guc_loader.c > > > @@ -801,3 +801,21 @@ void intel_guc_fini(struct drm_device *dev) > > > > > > guc_fw->fetch_status = UC_FIRMWARE_NONE; > > > } > > > + > > > +/** > > > + * intel_is_guc_valid() - Check to see if the GuC is fully loaded. > > > + * @dev: drm dedvice to check. > > > + * > > > + * This function will return true if the guc has been loaded and > > > + * has valid firmware. > > > + */ > > > +int intel_is_guc_valid(struct drm_i915_private *dev_priv) > > > +{ > > > + struct intel_uc_fw *guc_fw = &dev_priv->guc.guc_fw; > > > + > > > + if (guc_fw->load_status == UC_FIRMWARE_SUCCESS) > > > + return 1; > > > + else > > > + return 0; > > > +} > > > + > > > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h > > > index 03725fe..629fb5e 100644 > > > --- a/include/uapi/drm/i915_drm.h > > > +++ b/include/uapi/drm/i915_drm.h > > > @@ -388,6 +388,7 @@ typedef struct drm_i915_irq_wait { > > > #define I915_PARAM_HAS_POOLED_EU 38 > > > #define I915_PARAM_MIN_EU_IN_POOL 39 > > > #define I915_PARAM_MMAP_GTT_VERSION 40 > > > +#define I915_PARAM_HAS_GUC41 > > > > > > typedef struct drm_i915_getparam { > > > __s32 param; > > > -- > > > 2.7.4 > > > > > > ___ > > > Intel-gfx mailing list > > > Intel-gfx@lists.freedesktop.org > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx > > ___ > > Intel-gfx mailing list > > Intel-gfx@lists.freedesktop.org > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx > > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 6/8] drm/i915/huc: Add BXT HuC Loading Support
On Mon, Oct 03, 2016 at 11:43:00AM -0700, Anusha Srivatsa wrote: > From: Peter Antoine > > This patch adds the HuC Loading for the BXT. > Version 1.7 of the HuC firmware. > > v2: rebased. > v3: rebased. > changed file name to match the install package format. > v7: rebased. > v8: rebased. > > Signed-off-by: Anusha Srivatsa > Signed-off-by: Peter Antoine > Reviewed-by: David Gordon > --- > drivers/gpu/drm/i915/intel_huc_loader.c | 7 +++ > 1 file changed, 7 insertions(+) > > diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c > b/drivers/gpu/drm/i915/intel_huc_loader.c > index 1aaff67..87a6948 100644 > --- a/drivers/gpu/drm/i915/intel_huc_loader.c > +++ b/drivers/gpu/drm/i915/intel_huc_loader.c > @@ -50,6 +50,9 @@ > #define I915_SKL_HUC_UCODE "i915/skl_huc_ver01_07_1398.bin" > MODULE_FIRMWARE(I915_SKL_HUC_UCODE); > > +#define I915_BXT_HUC_UCODE "i915/bxt_huc_ver01_07_1398.bin" > +MODULE_FIRMWARE(I915_BXT_HUC_UCODE); > + This will need updating if the newer firmware version/name macros in intel_guc_loader.c are adopted. > /** > * intel_huc_load_ucode() - DMA's the firmware > * @dev: the drm device > @@ -158,6 +161,10 @@ void intel_huc_init(struct drm_device *dev) > fw_path = I915_SKL_HUC_UCODE; > huc_fw->major_ver_wanted = 1; > huc_fw->minor_ver_wanted = 7; > + } else if (IS_BROXTON(dev_priv)) { > + fw_path = I915_BXT_HUC_UCODE; > + huc_fw->major_ver_wanted = 1; > + huc_fw->minor_ver_wanted = 7; > } > > if (fw_path == NULL) > -- > 2.7.4 > > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 5/8] drm/i915/huc: Support HuC authentication
On Mon, Oct 03, 2016 at 11:42:59AM -0700, Anusha Srivatsa wrote: > From: Peter Antoine > > The HuC authentication is done by host2guc call. The HuC RSA keys > are sent to GuC for authentication. > > v2: rebased on top of drm-intel-nightly. > changed name format and upped version 1.7. > v3: rebased on top of drm-intel-nightly. > v4: changed wait_for_automic to wait_for > v5: rebased. > v7: rebased. > v8: rebased. > > Tested-by: Xiang Haihao > Signed-off-by: Anusha Srivatsa > Signed-off-by: Alex Dai > Signed-off-by: Peter Antoine > Reviewed-by: Dave Gordon > --- > drivers/gpu/drm/i915/i915_guc_submission.c | 65 > ++ > drivers/gpu/drm/i915/intel_guc_fwif.h | 1 + > drivers/gpu/drm/i915/intel_guc_loader.c| 2 + > 3 files changed, 68 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c > b/drivers/gpu/drm/i915/i915_guc_submission.c > index 4b92943..984b529 100644 > --- a/drivers/gpu/drm/i915/i915_guc_submission.c > +++ b/drivers/gpu/drm/i915/i915_guc_submission.c > @@ -25,6 +25,7 @@ > #include > #include "i915_drv.h" > #include "intel_guc.h" > +#include "intel_huc.h" > > /** > * DOC: GuC-based command submission > @@ -1110,3 +,67 @@ int intel_guc_resume(struct drm_device *dev) > > return host2guc_action(guc, data, ARRAY_SIZE(data)); > } > + > +/** > + * intel_huc_auth() - authenticate ucode > + * @dev: the drm device > + * > + * Triggers a HuC fw authentication request to the GuC via host-2-guc > + * interface. > + */ > +void intel_huc_auth(struct drm_device *dev) This function is primarily a guc action and must be in i915_guc_submission.c to use the static host2guc call. I think it would be clearer to name the function intel_guc_auth_huc and place the prototype in intel_guc.h instead of intel_huc.h where other wrappers of host2guc are prototyped. > +{ > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct intel_guc *guc = &dev_priv->guc; > + struct intel_huc *huc = &dev_priv->huc; > + struct i915_vma *vma; > + int ret; > + u32 data[2]; > + > + /* Bypass the case where there is no HuC firmware */ > + if (huc->huc_fw.fetch_status == UC_FIRMWARE_NONE || > + huc->huc_fw.load_status == UC_FIRMWARE_NONE) > + return; > + > + if (guc->guc_fw.load_status != UC_FIRMWARE_SUCCESS) { > + DRM_ERROR("HuC: GuC fw wasn't loaded. Can't authenticate"); > + return; > + } > + > + if (huc->huc_fw.load_status != UC_FIRMWARE_SUCCESS) { > + DRM_ERROR("HuC: fw wasn't loaded. Nothing to authenticate"); > + return; > + } > + > + vma = i915_gem_object_ggtt_pin(huc->huc_fw.uc_fw_obj, NULL, 0, 0, 0); > + if (IS_ERR(vma)) { > + DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma)); > + return; > + } > + > + > + /* Invalidate GuC TLB to let GuC take the latest updates to GTT. */ > + I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE); > + > + /* Specify auth action and where public signature is. It's stored > + * at the beginning of the gem object, before the fw bits Second sentence is wrong. RSA offset is after header and ucode. Please just remove this sentence. > + */ > + data[0] = HOST2GUC_ACTION_AUTHENTICATE_HUC; > + data[1] = i915_ggtt_offset(vma) + huc->huc_fw.rsa_offset; > + > + ret = host2guc_action(guc, data, ARRAY_SIZE(data)); > + if (ret) { > + DRM_ERROR("HuC: GuC did not ack Auth request\n"); > + goto out; > + } > + > + /* Check authentication status, it should be done by now */ > + ret = wait_for((I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED) > 0, 50); > + if (ret) { > + DRM_ERROR("HuC: Authentication failed\n"); > + goto out; > + } > + > +out: > + i915_vma_unpin(vma); > +} > diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h > b/drivers/gpu/drm/i915/intel_guc_fwif.h > index b38b6b4..57e6466 100644 > --- a/drivers/gpu/drm/i915/intel_guc_fwif.h > +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h > @@ -438,6 +438,7 @@ enum host2guc_action { > HOST2GUC_ACTION_ENTER_S_STATE = 0x501, > HOST2GUC_ACTION_EXIT_S_STATE = 0x502, > HOST2GUC_ACTION_SLPC_REQUEST = 0x3003, > + HOST2GUC_ACTION_AUTHENTICATE_HUC = 0x4000, > HOST2GUC_ACTION_LIMIT > }; > > diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c > b/drivers/gpu/drm/i915/intel_guc_loader.c > index 0d214b4..31a2b0a 100644 > --- a/drivers/gpu/drm/i915/intel_guc_loader.c > +++ b/drivers/gpu/drm/i915/intel_guc_loader.c > @@ -527,6 +527,8 @@ int intel_guc_setup(struct drm_device *dev) > intel_uc_fw_status_repr(guc_fw->fetch_status), > intel_uc_fw_status_repr(guc_fw->load_status)); > > + intel_huc_auth(dev); > + > if (i915.enable_guc_submission) { > err = i915_guc_submission_enable(dev_priv); > if (err) > -- > 2.7.4 > > __
Re: [Intel-gfx] [PATCH 3/8] drm/i915/huc: Add HuC fw loading support
On Thu, Oct 13, 2016 at 10:42:42AM -0700, Jeff McGee wrote: > On Mon, Oct 03, 2016 at 11:42:57AM -0700, Anusha Srivatsa wrote: > > From: Peter Antoine > > > > The HuC loading process is similar to GuC. The intel_uc_fw_fetch() > > is used for both cases. > > > > HuC loading needs to be before GuC loading. The WOPCM setting must > > be done early before loading any of them. > > > > v2: rebased on-top of drm-intel-nightly. > > removed if(HAS_GUC()) before the guc call. (D.Gordon) > > update huc_version number of format. > > v3: rebased to drm-intel-nightly, changed the file name format to > > match the one in the huc package. > > Changed dev->dev_private to to_i915() > > v4: moved function back to where it was. > > change wait_for_atomic to wait_for. > > v5: rebased + comment changes. > > v7: rebased. > > v8: rebased. > > > > Tested-by: Xiang Haihao > > Signed-off-by: Anusha Srivatsa > > Signed-off-by: Alex Dai > > Signed-off-by: Peter Antoine > > Reviewed-by: Dave Gordon > > --- > > drivers/gpu/drm/i915/Makefile | 1 + > > drivers/gpu/drm/i915/i915_drv.c | 3 + > > drivers/gpu/drm/i915/i915_drv.h | 3 + > > drivers/gpu/drm/i915/i915_guc_reg.h | 3 + > > drivers/gpu/drm/i915/intel_guc.h| 1 + > > drivers/gpu/drm/i915/intel_guc_loader.c | 6 +- > > drivers/gpu/drm/i915/intel_huc.h| 44 ++ > > drivers/gpu/drm/i915/intel_huc_loader.c | 268 > > > > 8 files changed, 327 insertions(+), 2 deletions(-) > > create mode 100644 drivers/gpu/drm/i915/intel_huc.h > > create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c > > > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > > index e6fe004..6e99c51 100644 > > --- a/drivers/gpu/drm/i915/Makefile > > +++ b/drivers/gpu/drm/i915/Makefile > > @@ -53,6 +53,7 @@ i915-y += i915_cmd_parser.o \ > > > > # general-purpose microcontroller (GuC) support > > i915-y += intel_guc_loader.o \ > > + intel_huc_loader.o \ > > i915_guc_submission.o > > > > # autogenerated null render state > > diff --git a/drivers/gpu/drm/i915/i915_drv.c > > b/drivers/gpu/drm/i915/i915_drv.c > > index 31b2b63..7af7bd6 100644 > > --- a/drivers/gpu/drm/i915/i915_drv.c > > +++ b/drivers/gpu/drm/i915/i915_drv.c > > @@ -613,6 +613,7 @@ static int i915_load_modeset_init(struct drm_device > > *dev) > > * working irqs for e.g. gmbus and dp aux transfers. */ > > intel_modeset_init(dev); > > > > + intel_huc_init(dev); > > intel_guc_init(dev); > > > > ret = i915_gem_init(dev); > > @@ -638,6 +639,7 @@ static int i915_load_modeset_init(struct drm_device > > *dev) > > cleanup_gem: > > i915_gem_fini(dev); > > cleanup_irq: > > + intel_huc_fini(dev); > > intel_guc_fini(dev); > > drm_irq_uninstall(dev); > > intel_teardown_gmbus(dev); > > @@ -1315,6 +1317,7 @@ void i915_driver_unload(struct drm_device *dev) > > /* Flush any outstanding unpin_work. */ > > drain_workqueue(dev_priv->wq); > > > > + intel_huc_fini(dev); > > intel_guc_fini(dev); > > i915_gem_fini(dev); > > intel_fbc_cleanup_cfb(dev_priv); > > diff --git a/drivers/gpu/drm/i915/i915_drv.h > > b/drivers/gpu/drm/i915/i915_drv.h > > index e0cb71c..625aa92 100644 > > --- a/drivers/gpu/drm/i915/i915_drv.h > > +++ b/drivers/gpu/drm/i915/i915_drv.h > > @@ -55,6 +55,7 @@ > > #include "intel_bios.h" > > #include "intel_dpll_mgr.h" > > #include "intel_guc.h" > > +#include "intel_huc.h" > > #include "intel_lrc.h" > > #include "intel_ringbuffer.h" > > > > @@ -1766,6 +1767,7 @@ struct drm_i915_private { > > > > struct intel_gvt gvt; > > > > + struct intel_huc huc; > > struct intel_guc guc; > > > > struct intel_csr csr; > > @@ -2822,6 +2824,7 @@ struct drm_i915_cmd_table { > > #define HAS_GUC(dev) (INTEL_INFO(dev)->has_guc) > > #define HAS_GUC_UCODE(dev) (HAS_GUC(dev)) > > #define HAS_GUC_SCHED(dev) (HAS_GUC(dev)) > > +#define HAS_HUC_UCODE(dev) (HAS_GUC(dev)) > > > > #define HAS_RESOURCE_STREAMER(dev) (INTEL_INFO(dev)->has_resource_streamer) > > > > diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h > > b/drivers/gpu/drm/i915/i915_g
Re: [Intel-gfx] [PATCH 4/8] drm/i915/huc: Add debugfs for HuC loading status check
Reviewed-by: Jeff McGee On Mon, Oct 03, 2016 at 11:42:58AM -0700, Anusha Srivatsa wrote: > From: Peter Antoine > > Add debugfs entry for HuC loading status check. > > v2: rebase on-top of drm-intel-nightly. > v3: rebased again. > v7: rebased. > v8: rebased. > > Tested-by: Xiang Haihao > Signed-off-by: Anusha Srivatsa > Signed-off-by: Alex Dai > Signed-off-by: Peter Antoine > Reviewed-by: Dave Gordon > --- > drivers/gpu/drm/i915/i915_debugfs.c | 31 +++ > 1 file changed, 31 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c > b/drivers/gpu/drm/i915/i915_debugfs.c > index 44258a8..7bd0e23 100644 > --- a/drivers/gpu/drm/i915/i915_debugfs.c > +++ b/drivers/gpu/drm/i915/i915_debugfs.c > @@ -2413,6 +2413,36 @@ static int i915_llc(struct seq_file *m, void *data) > return 0; > } > > +static int i915_huc_load_status_info(struct seq_file *m, void *data) > +{ > + struct drm_i915_private *dev_priv = node_to_i915(m->private); > + struct intel_uc_fw *huc_fw = &dev_priv->huc.huc_fw; > + > + if (!HAS_HUC_UCODE(dev_priv)) > + return 0; > + > + seq_puts(m, "HuC firmware status:\n"); > + seq_printf(m, "\tpath: %s\n", huc_fw->uc_fw_path); > + seq_printf(m, "\tfetch: %s\n", > + intel_uc_fw_status_repr(huc_fw->fetch_status)); > + seq_printf(m, "\tload: %s\n", > + intel_uc_fw_status_repr(huc_fw->load_status)); > + seq_printf(m, "\tversion wanted: %d.%d\n", > + huc_fw->major_ver_wanted, huc_fw->minor_ver_wanted); > + seq_printf(m, "\tversion found: %d.%d\n", > + huc_fw->major_ver_found, huc_fw->minor_ver_found); > + seq_printf(m, "\theader: offset is %d; size = %d\n", > + huc_fw->header_offset, huc_fw->header_size); > + seq_printf(m, "\tuCode: offset is %d; size = %d\n", > + huc_fw->ucode_offset, huc_fw->ucode_size); > + seq_printf(m, "\tRSA: offset is %d; size = %d\n", > + huc_fw->rsa_offset, huc_fw->rsa_size); > + > + seq_printf(m, "\nHuC status 0x%08x:\n", I915_READ(HUC_STATUS2)); > + > + return 0; > +} > + > static int i915_guc_load_status_info(struct seq_file *m, void *data) > { > struct drm_i915_private *dev_priv = node_to_i915(m->private); > @@ -4427,6 +4457,7 @@ static const struct drm_info_list i915_debugfs_list[] = > { > {"i915_guc_info", i915_guc_info, 0}, > {"i915_guc_load_status", i915_guc_load_status_info, 0}, > {"i915_guc_log_dump", i915_guc_log_dump, 0}, > + {"i915_huc_load_status", i915_huc_load_status_info, 0}, > {"i915_frequency_info", i915_frequency_info, 0}, > {"i915_hangcheck_info", i915_hangcheck_info, 0}, > {"i915_drpc_info", i915_drpc_info, 0}, > -- > 2.7.4 > > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 3/8] drm/i915/huc: Add HuC fw loading support
On Mon, Oct 03, 2016 at 11:42:57AM -0700, Anusha Srivatsa wrote: > From: Peter Antoine > > The HuC loading process is similar to GuC. The intel_uc_fw_fetch() > is used for both cases. > > HuC loading needs to be before GuC loading. The WOPCM setting must > be done early before loading any of them. > > v2: rebased on-top of drm-intel-nightly. > removed if(HAS_GUC()) before the guc call. (D.Gordon) > update huc_version number of format. > v3: rebased to drm-intel-nightly, changed the file name format to > match the one in the huc package. > Changed dev->dev_private to to_i915() > v4: moved function back to where it was. > change wait_for_atomic to wait_for. > v5: rebased + comment changes. > v7: rebased. > v8: rebased. > > Tested-by: Xiang Haihao > Signed-off-by: Anusha Srivatsa > Signed-off-by: Alex Dai > Signed-off-by: Peter Antoine > Reviewed-by: Dave Gordon > --- > drivers/gpu/drm/i915/Makefile | 1 + > drivers/gpu/drm/i915/i915_drv.c | 3 + > drivers/gpu/drm/i915/i915_drv.h | 3 + > drivers/gpu/drm/i915/i915_guc_reg.h | 3 + > drivers/gpu/drm/i915/intel_guc.h| 1 + > drivers/gpu/drm/i915/intel_guc_loader.c | 6 +- > drivers/gpu/drm/i915/intel_huc.h| 44 ++ > drivers/gpu/drm/i915/intel_huc_loader.c | 268 > > 8 files changed, 327 insertions(+), 2 deletions(-) > create mode 100644 drivers/gpu/drm/i915/intel_huc.h > create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > index e6fe004..6e99c51 100644 > --- a/drivers/gpu/drm/i915/Makefile > +++ b/drivers/gpu/drm/i915/Makefile > @@ -53,6 +53,7 @@ i915-y += i915_cmd_parser.o \ > > # general-purpose microcontroller (GuC) support > i915-y += intel_guc_loader.o \ > + intel_huc_loader.o \ > i915_guc_submission.o > > # autogenerated null render state > diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c > index 31b2b63..7af7bd6 100644 > --- a/drivers/gpu/drm/i915/i915_drv.c > +++ b/drivers/gpu/drm/i915/i915_drv.c > @@ -613,6 +613,7 @@ static int i915_load_modeset_init(struct drm_device *dev) >* working irqs for e.g. gmbus and dp aux transfers. */ > intel_modeset_init(dev); > > + intel_huc_init(dev); > intel_guc_init(dev); > > ret = i915_gem_init(dev); > @@ -638,6 +639,7 @@ static int i915_load_modeset_init(struct drm_device *dev) > cleanup_gem: > i915_gem_fini(dev); > cleanup_irq: > + intel_huc_fini(dev); > intel_guc_fini(dev); > drm_irq_uninstall(dev); > intel_teardown_gmbus(dev); > @@ -1315,6 +1317,7 @@ void i915_driver_unload(struct drm_device *dev) > /* Flush any outstanding unpin_work. */ > drain_workqueue(dev_priv->wq); > > + intel_huc_fini(dev); > intel_guc_fini(dev); > i915_gem_fini(dev); > intel_fbc_cleanup_cfb(dev_priv); > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index e0cb71c..625aa92 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -55,6 +55,7 @@ > #include "intel_bios.h" > #include "intel_dpll_mgr.h" > #include "intel_guc.h" > +#include "intel_huc.h" > #include "intel_lrc.h" > #include "intel_ringbuffer.h" > > @@ -1766,6 +1767,7 @@ struct drm_i915_private { > > struct intel_gvt gvt; > > + struct intel_huc huc; > struct intel_guc guc; > > struct intel_csr csr; > @@ -2822,6 +2824,7 @@ struct drm_i915_cmd_table { > #define HAS_GUC(dev) (INTEL_INFO(dev)->has_guc) > #define HAS_GUC_UCODE(dev) (HAS_GUC(dev)) > #define HAS_GUC_SCHED(dev) (HAS_GUC(dev)) > +#define HAS_HUC_UCODE(dev) (HAS_GUC(dev)) > > #define HAS_RESOURCE_STREAMER(dev) (INTEL_INFO(dev)->has_resource_streamer) > > diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h > b/drivers/gpu/drm/i915/i915_guc_reg.h > index a47e1e4..64e942a 100644 > --- a/drivers/gpu/drm/i915/i915_guc_reg.h > +++ b/drivers/gpu/drm/i915/i915_guc_reg.h > @@ -61,9 +61,12 @@ > #define DMA_ADDRESS_SPACE_GTT(8 << 16) > #define DMA_COPY_SIZE_MMIO(0xc310) > #define DMA_CTRL _MMIO(0xc314) > +#define HUC_UKERNEL (1<<9) > #define UOS_MOVE (1<<4) > #define START_DMA(1<<0) > #define DMA_GUC_WOPCM_OFFSET _MMIO(0xc340) > +#define HUC_LOADING_AGENT_VCR(0<<1) > +#define HUC_LOADING_AGENT_GUC(1<<1) > #define GUC_WOPCM_OFFSET_VALUE 0x8 /* 512KB */ > #define GUC_MAX_IDLE_COUNT _MMIO(0xC3E4) > > diff --git a/drivers/gpu/drm/i915/intel_guc.h > b/drivers/gpu/drm/i915/intel_guc.h > index 812e4ca..af76ffe 100644 > --- a/drivers/gpu/drm/i915/intel_guc.h > +++ b/drivers/gpu/drm/i915/intel_guc.h > @@ -160,6 +160,7 @@ extern const char *intel_uc_f
Re: [Intel-gfx] [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
On Mon, Oct 03, 2016 at 11:42:56AM -0700, Anusha Srivatsa wrote: > From: Peter Antoine > > HuC firmware css header has almost exactly same definition as GuC > firmware except for the sw_version. Also, add a new member fw_type > into intel_uc_fw to indicate what kind of fw it is. So, the loader > will pull right sw_version from header. > > v2: rebased on-top of drm-intel-nightly > v3: rebased on-top of drm-intel-nightly (again). > v4: rebased + spaces. > v7: rebased. > v8: rebased. > > Tested-by: Xiang Haihao > Signed-off-by: Anusha Srivatsa > Signed-off-by: Alex Dai > Signed-off-by: Peter Antoine > Reviewed-by: Dave Gordon > --- > drivers/gpu/drm/i915/intel_guc.h| 4 > drivers/gpu/drm/i915/intel_guc_fwif.h | 16 ++--- > drivers/gpu/drm/i915/intel_guc_loader.c | 41 > ++--- > 3 files changed, 45 insertions(+), 16 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_guc.h > b/drivers/gpu/drm/i915/intel_guc.h > index b134a41..812e4ca 100644 > --- a/drivers/gpu/drm/i915/intel_guc.h > +++ b/drivers/gpu/drm/i915/intel_guc.h > @@ -98,6 +98,9 @@ enum intel_uc_fw_status { > UC_FIRMWARE_SUCCESS > }; > > +#define UC_FW_TYPE_GUC 0 > +#define UC_FW_TYPE_HUC 1 > + > /* > * This structure encapsulates all the data needed during the process > * of fetching, caching, and loading the firmware image into the GuC. > @@ -115,6 +118,7 @@ struct intel_uc_fw { > uint16_t major_ver_found; > uint16_t minor_ver_found; > > + uint32_t fw_type; > uint32_t header_size; > uint32_t header_offset; > uint32_t rsa_size; > diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h > b/drivers/gpu/drm/i915/intel_guc_fwif.h > index e40db2d..b38b6b4 100644 > --- a/drivers/gpu/drm/i915/intel_guc_fwif.h > +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h > @@ -154,7 +154,7 @@ > * The GuC firmware layout looks like this: > * > * +---+ > - * |guc_css_header | > + * | uc_css_header | > * | | > * | contains major/minor version | > * +---+ > @@ -181,9 +181,16 @@ > * 3. Length info of each component can be found in header, in dwords. > * 4. Modulus and exponent key are not required by driver. They may not > appear > *in fw. So driver will load a truncated firmware in this case. > + * > + * HuC firmware layout is same as GuC firmware. > + * > + * HuC firmware css header is different. However, the only difference is > where > + * the version information is saved. The uc_css_header is unified to support > + * both. Driver should get HuC version from uc_css_header.huc_sw_version, > while > + * uc_css_header.guc_sw_version for GuC. > */ > > -struct guc_css_header { > +struct uc_css_header { > uint32_t module_type; > /* header_size includes all non-uCode bits, including css_header, rsa >* key, modulus key and exponent data. */ > @@ -214,7 +221,10 @@ struct guc_css_header { > > char username[8]; > char buildnumber[12]; > - uint32_t device_id; > + union { > + uint32_t device_id; > + uint32_t huc_sw_version; > + }; > uint32_t guc_sw_version; > uint32_t prod_preprod_fw; > uint32_t reserved[12]; I propose renaming the device_id field in this union to 'guc_client_branch_version'. GuC uses this position to store a client version and branch version. I'm not sure where the 'device_id' term came from. We don't reference this currently but may need to in the future so might as well name it properly. At the very least we should probably make it guc_device_id, to help indicate that it applies to guc fw only. In that same vein, can we make guc_sw_version into a union as below to reinforce the difference to huc? union { uint32_t guc_sw_version; uint32_t huc_reserved; }; Jeff > diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c > b/drivers/gpu/drm/i915/intel_guc_loader.c > index 493295d..0b863a1 100644 > --- a/drivers/gpu/drm/i915/intel_guc_loader.c > +++ b/drivers/gpu/drm/i915/intel_guc_loader.c > @@ -586,7 +586,7 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct > intel_uc_fw *uc_fw) > struct pci_dev *pdev = dev->pdev; > struct drm_i915_gem_object *obj; > const struct firmware *fw; > - struct guc_css_header *css; > + struct uc_css_header *css; > size_t size; > int err; > > @@ -603,19 +603,19 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct > intel_uc_fw *uc_fw) > uc_fw->uc_fw_path, fw); > > /* Check the size of the blob before examining buffer contents */ > - if (fw->size < sizeof(struct guc_css_header)) { > + if (fw->size < sizeof(struct uc_css_header)) { > DRM_NOTE("Firmware header is missing\n"); > goto fail; >
Re: [Intel-gfx] [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general
Reviewed-by: Jeff McGee On Mon, Oct 03, 2016 at 11:42:55AM -0700, Anusha Srivatsa wrote: > From: Peter Antoine > > Rename some of the GuC fw loading code to make them more general. We > will utilise them for HuC loading as well. > s/intel_guc_fw/intel_uc_fw/g > s/GUC_FIRMWARE/UC_FIRMWARE/g > > Struct intel_guc_fw is renamed to intel_uc_fw. Prefix of tts members, > such as 'guc' or 'guc_fw' either is renamed to 'uc' or removed for > same purpose. > > v2: rebased on top of nightly. > reapplied the search/replace as upstream code as changed. > v3: rebased again on drm-nightly. > v4: removed G from messages in shared fw fetch function. > v5: rebased. > v7: rebased. > v8: rebased. > > Signed-off-by: Anusha Srivatsa > Signed-off-by: Alex Dai > Signed-off-by: Peter Antoine > Reviewed-by: Dave Gordon > --- > drivers/gpu/drm/i915/i915_debugfs.c| 12 +-- > drivers/gpu/drm/i915/i915_guc_submission.c | 4 +- > drivers/gpu/drm/i915/intel_guc.h | 39 > drivers/gpu/drm/i915/intel_guc_loader.c| 156 > ++--- > 4 files changed, 106 insertions(+), 105 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c > b/drivers/gpu/drm/i915/i915_debugfs.c > index 4fb9d82..44258a8 100644 > --- a/drivers/gpu/drm/i915/i915_debugfs.c > +++ b/drivers/gpu/drm/i915/i915_debugfs.c > @@ -2416,7 +2416,7 @@ static int i915_llc(struct seq_file *m, void *data) > static int i915_guc_load_status_info(struct seq_file *m, void *data) > { > struct drm_i915_private *dev_priv = node_to_i915(m->private); > - struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw; > + struct intel_uc_fw *guc_fw = &dev_priv->guc.guc_fw; > u32 tmp, i; > > if (!HAS_GUC_UCODE(dev_priv)) > @@ -2424,15 +2424,15 @@ static int i915_guc_load_status_info(struct seq_file > *m, void *data) > > seq_printf(m, "GuC firmware status:\n"); > seq_printf(m, "\tpath: %s\n", > - guc_fw->guc_fw_path); > + guc_fw->uc_fw_path); > seq_printf(m, "\tfetch: %s\n", > - intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status)); > + intel_uc_fw_status_repr(guc_fw->fetch_status)); > seq_printf(m, "\tload: %s\n", > - intel_guc_fw_status_repr(guc_fw->guc_fw_load_status)); > + intel_uc_fw_status_repr(guc_fw->load_status)); > seq_printf(m, "\tversion wanted: %d.%d\n", > - guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted); > + guc_fw->major_ver_wanted, guc_fw->minor_ver_wanted); > seq_printf(m, "\tversion found: %d.%d\n", > - guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found); > + guc_fw->major_ver_found, guc_fw->minor_ver_found); > seq_printf(m, "\theader: offset is %d; size = %d\n", > guc_fw->header_offset, guc_fw->header_size); > seq_printf(m, "\tuCode: offset is %d; size = %d\n", > diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c > b/drivers/gpu/drm/i915/i915_guc_submission.c > index 43358e1..4b92943 100644 > --- a/drivers/gpu/drm/i915/i915_guc_submission.c > +++ b/drivers/gpu/drm/i915/i915_guc_submission.c > @@ -1072,7 +1072,7 @@ int intel_guc_suspend(struct drm_device *dev) > struct i915_gem_context *ctx; > u32 data[3]; > > - if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS) > + if (guc->guc_fw.load_status != UC_FIRMWARE_SUCCESS) > return 0; > > ctx = dev_priv->kernel_context; > @@ -1098,7 +1098,7 @@ int intel_guc_resume(struct drm_device *dev) > struct i915_gem_context *ctx; > u32 data[3]; > > - if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS) > + if (guc->guc_fw.load_status != UC_FIRMWARE_SUCCESS) > return 0; > > ctx = dev_priv->kernel_context; > diff --git a/drivers/gpu/drm/i915/intel_guc.h > b/drivers/gpu/drm/i915/intel_guc.h > index b1ba869..b134a41 100644 > --- a/drivers/gpu/drm/i915/intel_guc.h > +++ b/drivers/gpu/drm/i915/intel_guc.h > @@ -91,29 +91,29 @@ struct i915_guc_client { > uint64_t submissions[I915_NUM_ENGINES]; > }; > > -enum intel_guc_fw_status { > - GUC_FIRMWARE_FAIL = -1, > - GUC_FIRMWARE_NONE = 0, > - GUC_FIRMWARE_PENDING, > - GUC_FIRMWARE_SUCCESS > +enum intel_uc_fw_status { > + UC_FIRMWARE_FAIL = -1, > + UC_FIRMWARE_NONE = 0, > + UC_FIRMWARE_PENDING, > + UC_FIRMWARE_SUCCESS > }; > >
Re: [Intel-gfx] [PATCH] drm/i915/gen9: Add WaVFEStateAfterPipeControlwithMediaStateClear
On Fri, Jun 03, 2016 at 12:40:00PM +0100, Arun Siluvery wrote: > Kernel only need to add a register to HW whitelist, required for a > preemption related issue. > > Reference: HSD#2131039 > Signed-off-by: Arun Siluvery > --- > drivers/gpu/drm/i915/i915_reg.h | 1 + > drivers/gpu/drm/i915/intel_ringbuffer.c | 5 + > 2 files changed, 6 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index e307725..1f6040a 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -6072,6 +6072,7 @@ enum skl_disp_power_wells { > #define GEN9_TSG_BARRIER_ACK_DISABLE(1<<8) > > #define GEN9_CS_DEBUG_MODE1 _MMIO(0x20ec) > +#define GEN9_CTX_PREEMPT_REG _MMIO(0x2248) > #define GEN8_CS_CHICKEN1 _MMIO(0x2580) > > /* GEN7 chicken */ > diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c > b/drivers/gpu/drm/i915/intel_ringbuffer.c > index 8d35a39..1f9d3a4 100644 > --- a/drivers/gpu/drm/i915/intel_ringbuffer.c > +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c > @@ -987,6 +987,11 @@ static int gen9_init_workarounds(struct intel_engine_cs > *engine) > I915_WRITE(GEN8_L3SQCREG4, (I915_READ(GEN8_L3SQCREG4) | > GEN8_LQSC_FLUSH_COHERENT_LINES)); > > + /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt */ > + ret= wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG); > + if (ret) > + return ret; > + > /* WaEnablePreemptionGranularityControlByUMD:skl,bxt */ > ret= wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1); > if (ret) > -- > 1.9.1 > Reviewed-by: Jeff McGee > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v2 2/2] drm/i915: resize the GuC WOPCM for rc6
On Thu, Jan 21, 2016 at 06:11:01PM +, Peter Antoine wrote: > This patch resizes the GuC WOPCM to so that the GuC and the RC6 memory > spaces do not overlap. > > Issue: https://jira01.devtools.intel.com/browse/VIZ-6638 > Signed-off-by: Peter Antoine > --- > drivers/gpu/drm/i915/i915_guc_reg.h | 3 ++- > drivers/gpu/drm/i915/intel_guc_loader.c | 6 +- > 2 files changed, 7 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h > b/drivers/gpu/drm/i915/i915_guc_reg.h > index 685c799..cb938b0 100644 > --- a/drivers/gpu/drm/i915/i915_guc_reg.h > +++ b/drivers/gpu/drm/i915/i915_guc_reg.h > @@ -58,7 +58,8 @@ > #define GUC_MAX_IDLE_COUNT _MMIO(0xC3E4) > > #define GUC_WOPCM_SIZE _MMIO(0xc050) > -#define GUC_WOPCM_SIZE_VALUE (0x80 << 12) /* 512KB */ > +#define GUC_WOPCM_SIZE_VALUE (0x80 << 12)/* 512KB */ > +#define BXT_GUC_WOPCM_SIZE_VALUE (0x70 << 12)/* 448KB */ > > /* GuC addresses below GUC_WOPCM_TOP don't map through the GTT */ > #define GUC_WOPCM_TOP (GUC_WOPCM_SIZE_VALUE) Should GUC_WOPCM_TOP be dynamically assigned the proper value, or is it sufficient to leave at the max possible WOPCM size? If the later, might be worth a comment. -Jeff > diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c > b/drivers/gpu/drm/i915/intel_guc_loader.c > index 8182d11..69c85d1 100644 > --- a/drivers/gpu/drm/i915/intel_guc_loader.c > +++ b/drivers/gpu/drm/i915/intel_guc_loader.c > @@ -304,7 +304,11 @@ static int guc_ucode_xfer(struct drm_i915_private > *dev_priv) > intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); > > /* init WOPCM */ > - I915_WRITE(GUC_WOPCM_SIZE, GUC_WOPCM_SIZE_VALUE); > + if (IS_BROXTON(dev)) > + I915_WRITE(GUC_WOPCM_SIZE, BXT_GUC_WOPCM_SIZE_VALUE); > + else > + I915_WRITE(GUC_WOPCM_SIZE, GUC_WOPCM_SIZE_VALUE); > + > I915_WRITE(DMA_GUC_WOPCM_OFFSET, GUC_WOPCM_OFFSET_VALUE); > > /* Enable MIA caching. GuC clock gating is disabled. */ > -- > 1.9.1 > > ___ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx