* [U-Boot] [RFC 1/1] image: Add TEE loading to FIT loadable processing
From: Simon Glass @ 2016-11-14 20:44 UTC (permalink / raw)
To: u-boot
In-Reply-To: <20161114194925.17117-2-afd@ti.com>
Hi Andrew,
On 14 November 2016 at 12:49, Andrew F. Davis <afd@ti.com> wrote:
> To help automate the loading of a TEE image during the boot we add a new
> FIT section type 'tee', when we see this type while loading the loadable
> sections we automatically call the platforms TEE processing function on
> this image section.
>
> Signed-off-by: Andrew F. Davis <afd@ti.com>
> ---
> Kconfig | 10 ++++++++++
> common/image.c | 18 ++++++++++++++++++
> include/image.h | 15 +++++++++++++++
> 3 files changed, 43 insertions(+)
>
> diff --git a/Kconfig b/Kconfig
> index 1263d0b..97cf7c8 100644
> --- a/Kconfig
> +++ b/Kconfig
> @@ -291,6 +291,16 @@ config FIT_IMAGE_POST_PROCESS
> injected into the FIT creation (i.e. the blobs would have been pre-
> processed before being added to the FIT image).
>
> +config FIT_IMAGE_TEE_PROCESS
> + bool "Enable processing of TEE images during FIT loading by U-Boot"
> + depends on FIT && TI_SECURE_DEVICE
This is a generic option so I don't think it should depend on TI.
> + help
> + Allows platforms to perform processing, such as authentication and
> + installation, on TEE images extracted from FIT images in a platform
> + or board specific way. In order to use this feature a platform or
> + board-specific implementation of board_tee_image_process() must be
> + provided.
> +
> config SPL_DFU_SUPPORT
> bool "Enable SPL with DFU to load binaries to memory device"
> depends on USB
> diff --git a/common/image.c b/common/image.c
> index 7604494..4552ca5 100644
> --- a/common/image.c
> +++ b/common/image.c
> @@ -165,6 +165,7 @@ static const table_entry_t uimage_type[] = {
> { IH_TYPE_ZYNQIMAGE, "zynqimage", "Xilinx Zynq Boot Image" },
> { IH_TYPE_ZYNQMPIMAGE, "zynqmpimage", "Xilinx ZynqMP Boot Image" },
> { IH_TYPE_FPGA, "fpga", "FPGA Image" },
> + { IH_TYPE_TEE, "tee", "TEE OS Image",},
Perhaps write out TEE in full? It's a bit cryptic.
> { -1, "", "", },
> };
>
> @@ -1408,6 +1409,8 @@ int boot_get_loadable(int argc, char * const argv[], bootm_headers_t *images,
> int fit_img_result;
> const char *uname;
>
> + uint8_t img_type;
> +
> /* Check to see if the images struct has a FIT configuration */
> if (!genimg_has_config(images)) {
> debug("## FIT configuration was not specified\n");
> @@ -1447,6 +1450,21 @@ int boot_get_loadable(int argc, char * const argv[], bootm_headers_t *images,
> /* Something went wrong! */
> return fit_img_result;
> }
> +
> + fit_img_result = fit_image_get_node(buf, uname);
> + if (fit_img_result < 0) {
> + /* Something went wrong! */
> + return fit_img_result;
> + }
> + fit_img_result = fit_image_get_type(buf, fit_img_result, &img_type);
> + if (fit_img_result < 0) {
> + /* Something went wrong! */
> + return fit_img_result;
> + }
> +#if defined(CONFIG_FIT_IMAGE_TEE_PROCESS)
> + if (img_type == IH_TYPE_TEE)
> + board_tee_image_process(img_data, img_len);
> +#endif
Instead of putting this here, I think it would be better for
boot_get_loadable() to return the correct values for ld_start and
ld_len. Perhaps you need to pass it the loadable index to load, so it
is called multiple times? The only caller is bootm_find_images().
It is too ugly, I think, to check the image type in the 'load'
function, and do special things.
> }
> break;
> default:
> diff --git a/include/image.h b/include/image.h
> index 2b1296c..57084c8 100644
> --- a/include/image.h
> +++ b/include/image.h
> @@ -279,6 +279,7 @@ enum {
> IH_TYPE_ZYNQMPIMAGE, /* Xilinx ZynqMP Boot Image */
> IH_TYPE_FPGA, /* FPGA Image */
> IH_TYPE_VYBRIDIMAGE, /* VYBRID .vyb Image */
> + IH_TYPE_TEE, /* Trusted Execution Environment OS Image */
>
> IH_TYPE_COUNT, /* Number of image types */
> };
> @@ -1263,4 +1264,18 @@ int board_fit_config_name_match(const char *name);
> void board_fit_image_post_process(void **p_image, size_t *p_size);
> #endif /* CONFIG_SPL_FIT_IMAGE_POST_PROCESS */
>
> +#ifdef CONFIG_FIT_IMAGE_TEE_PROCESS
I don't think you should have this #ifdef in the header file.
> +/**
> + * board_fit_tee_process() - Do any needed processing on a loaded TEE image
> + *
> + * This is used to verify, decrypt, and/or install a TEE in a platform or
> + * board specific way.
nit: board-specific
> + *
> + * @tee_image: pointer to the image
What format is the image?
> + * @tee_size: the image size
> + * @return no return value (failure should be handled internally)
> + */
> +void board_tee_image_process(void *tee_image, size_t tee_size);
I think it's a good idea to return an error code here, since the
function may fail.
> +#endif /* CONFIG_FIT_IMAGE_TEE_PROCESS */
> +
> #endif /* __IMAGE_H__ */
> --
> 2.10.1
>
Regards,
SImon
^ permalink raw reply
* [U-Boot] [PATCH v2 1/4] Introduce CONFIG_SPL_ABORT_ON_NON_FIT_IMAGE
From: Simon Glass @ 2016-11-14 20:44 UTC (permalink / raw)
To: u-boot
In-Reply-To: <20161114191419.14214-2-afd@ti.com>
Hi Andrew,
On 14 November 2016 at 12:14, Andrew F. Davis <afd@ti.com> wrote:
> Introduce CONFIG_SPL_ABORT_ON_NON_FIT_IMAGE. An SPL which define
> this will abort image loading if the image is not a FIT image.
>
> Signed-off-by: Andrew F. Davis <afd@ti.com>
> ---
> Kconfig | 9 +++++++++
> common/spl/spl.c | 5 +++++
> 2 files changed, 14 insertions(+)
>
> diff --git a/Kconfig b/Kconfig
> index 1263d0b..eefebef 100644
> --- a/Kconfig
> +++ b/Kconfig
> @@ -291,6 +291,15 @@ config FIT_IMAGE_POST_PROCESS
> injected into the FIT creation (i.e. the blobs would have been pre-
> processed before being added to the FIT image).
>
> +config SPL_ABORT_ON_NON_FIT_IMAGE
We already have CONFIG_IMAGE_FORMAT_LEGACY so how about
CONFIG_SPL_IMAGE_FORMAT_LEGACY instead? It can default to y if secure
boot is disabled.
> + bool "Disable SPL loading of non-FIT images"
> + default y if SPL_FIT_SIGNATURE
> + help
> + SPL will not load and image if it is not a FIT image. This is
> + useful for devices that only support authentication/encryption
> + through SPL FIT loading paths and do not want SPL falling back
> + to legacy image loading when a non-FIT image is present.
> +
> config SPL_DFU_SUPPORT
> bool "Enable SPL with DFU to load binaries to memory device"
> depends on USB
> diff --git a/common/spl/spl.c b/common/spl/spl.c
> index bdb165a..3d8bee9 100644
> --- a/common/spl/spl.c
> +++ b/common/spl/spl.c
> @@ -93,6 +93,10 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
> int spl_parse_image_header(struct spl_image_info *spl_image,
> const struct image_header *header)
> {
> +#ifdef CONFIG_SPL_ABORT_ON_NON_FIT_IMAGE
> + /* non-FIT image found, proceed to other boot methods. */
> + return -EINVAL;
How about -EPROTONOSUPPORT since the request is not really invalid.
> +#else
> u32 header_size = sizeof(struct image_header);
>
> if (image_get_magic(header) == IH_MAGIC) {
> @@ -156,6 +160,7 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
> spl_set_header_raw_uboot(spl_image);
> #endif
> }
> +#endif
> return 0;
> }
>
> --
> 2.10.1
>
Regards,
Simon
^ permalink raw reply
* Re: [PATCH v2] cpufreq: conservative: Decrease frequency faster when the update deferred
From: Rafael J. Wysocki @ 2016-11-14 20:44 UTC (permalink / raw)
To: Stratos Karafotis
Cc: Rafael J. Wysocki, Viresh Kumar, linux-pm@vger.kernel.org, LKML
In-Reply-To: <691e286d-249b-e450-2df1-8421d83e6a46@semaphore.gr>
On Sat, Nov 12, 2016 at 10:04 PM, Stratos Karafotis
<stratosk@semaphore.gr> wrote:
> Conservative governor changes the CPU frequency in steps.
> That means that if a CPU runs at max frequency, it will need several
> sampling periods to return to min frequency when the workload
> is finished.
>
> If the update function that calculates the load and target frequency
> is deferred, the governor might need even more time to decrease the
> frequency.
>
> This may have impact to power consumption and after all conservative
> should decrease the frequency if there is no workload at every sampling
> rate.
>
> To resolve the above issue calculate the number of sampling periods
> that the update is deferred. Considering that for each sampling period
> conservative should drop the frequency by a freq_step because the
> CPU was idle apply the proper subtraction to requested frequency.
>
> Below, the kernel trace with and without this patch. First an
> intensive workload is applied on a specific CPU. Then the workload
> is removed and the CPU goes to idle.
>
> WITHOUT
>
> <idle>-0 [007] dN.. 620.329153: cpu_idle: state=4294967295 cpu_id=7
> kworker/7:2-556 [007] .... 620.350857: cpu_frequency: state=1700000 cpu_id=7
> kworker/7:2-556 [007] .... 620.370856: cpu_frequency: state=1900000 cpu_id=7
> kworker/7:2-556 [007] .... 620.390854: cpu_frequency: state=2100000 cpu_id=7
> kworker/7:2-556 [007] .... 620.411853: cpu_frequency: state=2200000 cpu_id=7
> kworker/7:2-556 [007] .... 620.432854: cpu_frequency: state=2400000 cpu_id=7
> kworker/7:2-556 [007] .... 620.453854: cpu_frequency: state=2600000 cpu_id=7
> kworker/7:2-556 [007] .... 620.494856: cpu_frequency: state=2900000 cpu_id=7
> kworker/7:2-556 [007] .... 620.515856: cpu_frequency: state=3100000 cpu_id=7
> kworker/7:2-556 [007] .... 620.536858: cpu_frequency: state=3300000 cpu_id=7
> kworker/7:2-556 [007] .... 620.557857: cpu_frequency: state=3401000 cpu_id=7
> <idle>-0 [007] d... 669.591363: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 669.591939: cpu_idle: state=4294967295 cpu_id=7
> <idle>-0 [007] d... 669.591980: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] dN.. 669.591989: cpu_idle: state=4294967295 cpu_id=7
> ...
> <idle>-0 [007] d... 670.201224: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 670.221975: cpu_idle: state=4294967295 cpu_id=7
> kworker/7:2-556 [007] .... 670.222016: cpu_frequency: state=3300000 cpu_id=7
> <idle>-0 [007] d... 670.222026: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 670.234964: cpu_idle: state=4294967295 cpu_id=7
> ...
> <idle>-0 [007] d... 670.801251: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 671.236046: cpu_idle: state=4294967295 cpu_id=7
> kworker/7:2-556 [007] .... 671.236073: cpu_frequency: state=3100000 cpu_id=7
> <idle>-0 [007] d... 671.236112: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 671.393437: cpu_idle: state=4294967295 cpu_id=7
> ...
> <idle>-0 [007] d... 671.401277: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 671.404083: cpu_idle: state=4294967295 cpu_id=7
> kworker/7:2-556 [007] .... 671.404111: cpu_frequency: state=2900000 cpu_id=7
> <idle>-0 [007] d... 671.404125: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 671.404974: cpu_idle: state=4294967295 cpu_id=7
> ...
> <idle>-0 [007] d... 671.501180: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 671.995414: cpu_idle: state=4294967295 cpu_id=7
> kworker/7:2-556 [007] .... 671.995459: cpu_frequency: state=2800000 cpu_id=7
> <idle>-0 [007] d... 671.995469: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 671.996287: cpu_idle: state=4294967295 cpu_id=7
> ...
> <idle>-0 [007] d... 672.001305: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 672.078374: cpu_idle: state=4294967295 cpu_id=7
> kworker/7:2-556 [007] .... 672.078410: cpu_frequency: state=2600000 cpu_id=7
> <idle>-0 [007] d... 672.078419: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 672.158020: cpu_idle: state=4294967295 cpu_id=7
> kworker/7:2-556 [007] .... 672.158040: cpu_frequency: state=2400000 cpu_id=7
> <idle>-0 [007] d... 672.158044: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 672.160038: cpu_idle: state=4294967295 cpu_id=7
> ...
> <idle>-0 [007] d... 672.234557: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 672.237121: cpu_idle: state=4294967295 cpu_id=7
> kworker/7:2-556 [007] .... 672.237174: cpu_frequency: state=2100000 cpu_id=7
> <idle>-0 [007] d... 672.237186: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 672.237778: cpu_idle: state=4294967295 cpu_id=7
> ...
> <idle>-0 [007] d... 672.267902: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 672.269860: cpu_idle: state=4294967295 cpu_id=7
> kworker/7:2-556 [007] .... 672.269906: cpu_frequency: state=1900000 cpu_id=7
> <idle>-0 [007] d... 672.269914: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 672.271902: cpu_idle: state=4294967295 cpu_id=7
> ...
> <idle>-0 [007] d... 672.751342: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 672.823056: cpu_idle: state=4294967295 cpu_id=7
> kworker/7:2-556 [007] .... 672.823095: cpu_frequency: state=1600000 cpu_id=7
>
> WITH
>
> <idle>-0 [007] dN.. 4380.928009: cpu_idle: state=4294967295 cpu_id=7
> kworker/7:2-399 [007] .... 4380.949767: cpu_frequency: state=2000000 cpu_id=7
> kworker/7:2-399 [007] .... 4380.969765: cpu_frequency: state=2200000 cpu_id=7
> kworker/7:2-399 [007] .... 4381.009766: cpu_frequency: state=2500000 cpu_id=7
> kworker/7:2-399 [007] .... 4381.029767: cpu_frequency: state=2600000 cpu_id=7
> kworker/7:2-399 [007] .... 4381.049769: cpu_frequency: state=2800000 cpu_id=7
> kworker/7:2-399 [007] .... 4381.069769: cpu_frequency: state=3000000 cpu_id=7
> kworker/7:2-399 [007] .... 4381.089771: cpu_frequency: state=3100000 cpu_id=7
> kworker/7:2-399 [007] .... 4381.109772: cpu_frequency: state=3400000 cpu_id=7
> kworker/7:2-399 [007] .... 4381.129773: cpu_frequency: state=3401000 cpu_id=7
> <idle>-0 [007] d... 4428.226159: cpu_idle: state=1 cpu_id=7
> <idle>-0 [007] d... 4428.226176: cpu_idle: state=4294967295 cpu_id=7
> <idle>-0 [007] d... 4428.226181: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 4428.227177: cpu_idle: state=4294967295 cpu_id=7
> ...
> <idle>-0 [007] d... 4428.551640: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 4428.649239: cpu_idle: state=4294967295 cpu_id=7
> kworker/7:2-399 [007] .... 4428.649268: cpu_frequency: state=2800000 cpu_id=7
> <idle>-0 [007] d... 4428.649278: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 4428.689856: cpu_idle: state=4294967295 cpu_id=7
> ...
> <idle>-0 [007] d... 4428.799542: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 4428.801683: cpu_idle: state=4294967295 cpu_id=7
> kworker/7:2-399 [007] .... 4428.801748: cpu_frequency: state=1700000 cpu_id=7
> <idle>-0 [007] d... 4428.801761: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 4428.806545: cpu_idle: state=4294967295 cpu_id=7
> ...
> <idle>-0 [007] d... 4429.051880: cpu_idle: state=4 cpu_id=7
> <idle>-0 [007] d... 4429.086240: cpu_idle: state=4294967295 cpu_id=7
> kworker/7:2-399 [007] .... 4429.086293: cpu_frequency: state=1600000 cpu_id=7
>
> Without the patch the CPU dropped to min frequency after 3.2s
> With the patch applied the CPU dropped to min frequency after 0.86s
>
> Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
> ---
> v1 -> v2
> - Use correct terminology in change log
> - Change the member variable name from 'deferred_periods' to 'idle_periods'
> - Fix format issue
>
> drivers/cpufreq/cpufreq_conservative.c | 14 +++++++++++++-
> drivers/cpufreq/cpufreq_governor.c | 18 +++++++++++++-----
> drivers/cpufreq/cpufreq_governor.h | 1 +
> 3 files changed, 27 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
> index fa5ece3..d787772 100644
> --- a/drivers/cpufreq/cpufreq_conservative.c
> +++ b/drivers/cpufreq/cpufreq_conservative.c
> @@ -73,7 +73,19 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy)
> */
> if (cs_tuners->freq_step == 0)
> goto out;
> -
> + /*
> + * Decrease requested_freq for each idle period that we didn't
> + * update the frequency
> + */
> + if (policy_dbs->idle_periods < UINT_MAX) {
> + unsigned int freq_target = policy_dbs->idle_periods *
> + get_freq_target(cs_tuners, policy);
> + if (requested_freq > freq_target)
> + requested_freq -= freq_target;
> + else
> + requested_freq = policy->min;
> + policy_dbs->idle_periods = UINT_MAX;
> + }
> /*
> * If requested_freq is out of range, it is likely that the limits
> * changed in the meantime, so fall back to current frequency in that
> diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
> index 3729474..1bc7137 100644
> --- a/drivers/cpufreq/cpufreq_governor.c
> +++ b/drivers/cpufreq/cpufreq_governor.c
> @@ -117,7 +117,7 @@ unsigned int dbs_update(struct cpufreq_policy *policy)
> struct policy_dbs_info *policy_dbs = policy->governor_data;
> struct dbs_data *dbs_data = policy_dbs->dbs_data;
> unsigned int ignore_nice = dbs_data->ignore_nice_load;
> - unsigned int max_load = 0;
> + unsigned int max_load = 0, idle_periods = UINT_MAX;
> unsigned int sampling_rate, io_busy, j;
>
> /*
> @@ -163,8 +163,12 @@ unsigned int dbs_update(struct cpufreq_policy *policy)
> * calls, so the previous load value can be used then.
> */
> load = j_cdbs->prev_load;
> - } else if (unlikely(time_elapsed > 2 * sampling_rate &&
> - j_cdbs->prev_load)) {
> + } else if (unlikely(time_elapsed > 2 * sampling_rate)) {
> + unsigned int periods = time_elapsed / sampling_rate;
> +
> + if (periods < idle_periods)
> + idle_periods = periods;
> +
> /*
> * If the CPU had gone completely idle and a task has
> * just woken up on this CPU now, it would be unfair to
> @@ -189,8 +193,10 @@ unsigned int dbs_update(struct cpufreq_policy *policy)
> * 'time_elapsed' (as compared to the sampling rate)
> * indicates this scenario.
> */
> - load = j_cdbs->prev_load;
> - j_cdbs->prev_load = 0;
> + if (j_cdbs->prev_load) {
> + load = j_cdbs->prev_load;
> + j_cdbs->prev_load = 0;
> + }
> } else {
> if (time_elapsed >= idle_time) {
> load = 100 * (time_elapsed - idle_time) / time_elapsed;
> @@ -218,6 +224,8 @@ unsigned int dbs_update(struct cpufreq_policy *policy)
> if (load > max_load)
> max_load = load;
> }
> + policy_dbs->idle_periods = idle_periods;
> +
> return max_load;
> }
> EXPORT_SYMBOL_GPL(dbs_update);
I have a murky suspicion that the changes in dbs_update() are going to
break something. I need to recall what it was, though.
Thanks,
Rafael
^ permalink raw reply
* [U-Boot] [PATCH 4/9] w1: Add 1-Wire gpio driver
From: Simon Glass @ 2016-11-14 20:44 UTC (permalink / raw)
To: u-boot
In-Reply-To: <20161114133536.brde45x2hdp2sjdo@lukather>
Hi Maxime,
On 14 November 2016 at 06:35, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi Simon,
>
> On Fri, Nov 11, 2016 at 09:17:20AM -0700, Simon Glass wrote:
>> Hi Maxime,
>>
>> On 8 November 2016 at 03:06, Maxime Ripard
>> <maxime.ripard@free-electrons.com> wrote:
>> > Add a bus driver for bitbanging a 1-Wire bus over a GPIO.
>> >
>> > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>> > ---
>> > drivers/w1/Kconfig | 6 ++-
>> > drivers/w1/Makefile | 1 +-
>> > drivers/w1/w1-gpio.c | 160 ++++++++++++++++++++++++++++++++++++++++++++-
>> > 3 files changed, 167 insertions(+), 0 deletions(-)
>> > create mode 100644 drivers/w1/w1-gpio.c
>> >
>> > diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig
>> > index 0c056b4c06a9..ccc3ae15db86 100644
>> > --- a/drivers/w1/Kconfig
>> > +++ b/drivers/w1/Kconfig
>> > @@ -12,6 +12,12 @@ config W1
>> >
>> > if W1
>> >
>> > +config W1_GPIO
>> > + bool "Enable 1-Wire GPIO bitbanging"
>> > + depends on DM_GPIO
>> > + help
>> > + Emulate a 1-Wire bus using a GPIO.
>>
>> Any more details? How many GPIOs? Any particular chips that are
>> supported?
>
> 1-Wire works on a single line, hence it's name. You usually have
> either a controller (which is quite rare, but some SoCs have one) or
> you can bitbang the bus. It's low bandwidth enough that it doesn't
> really matter.
>
> I'm not sure if it answers your question. I'll address your other
> comments.
OK thanks - please can you add a bit more detail into the help.
Regards,
Simon
^ permalink raw reply
* [U-Boot] [PATCH 4/4] rk3036: enable the vbus regulator when borad_init
From: Simon Glass @ 2016-11-14 20:44 UTC (permalink / raw)
To: u-boot
In-Reply-To: <58298CD5.8000608@rock-chips.com>
Hi Kever,
On 14 November 2016 at 03:07, Kever Yang <kever.yang@rock-chips.com> wrote:
> Hi Simon,
>
> On 11/12/2016 12:17 AM, Simon Glass wrote:
>>
>> Hi Kever,
>>
>> On 8 November 2016 at 03:13, Kever Yang <kever.yang@rock-chips.com> wrote:
>>>
>>> enable the vbus for usb host in board_init().
>>
>> Note 'borad_init' typo in subject.
>
>
> Will fix in next version.
>>
>>
>>> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
>>> ---
>>>
>>> arch/arm/mach-rockchip/rk3036-board.c | 20 ++++++++++++++++++++
>>> 1 file changed, 20 insertions(+)
>>>
>>> diff --git a/arch/arm/mach-rockchip/rk3036-board.c
>>> b/arch/arm/mach-rockchip/rk3036-board.c
>>> index bf2b268..90d3d33 100644
>>> --- a/arch/arm/mach-rockchip/rk3036-board.c
>>> +++ b/arch/arm/mach-rockchip/rk3036-board.c
>>> @@ -16,6 +16,7 @@
>>> #include <asm/arch/sdram_rk3036.h>
>>> #include <asm/gpio.h>
>>> #include <dm/pinctrl.h>
>>> +#include <power/regulator.h>
>>>
>>> DECLARE_GLOBAL_DATA_PTR;
>>>
>>> @@ -57,7 +58,26 @@ int board_late_init(void)
>>>
>>> int board_init(void)
>>> {
>>> + int ret;
>>> + struct udevice *regulator;
>>> +
>>> + ret = regulator_get_by_platname("vcc5v0_host", ®ulator);
>>
>> Can this be done in the USB driver? Then you might be able to use
>> device_get_supply_regulator().
>
>
> In dwc2 controller, there do have a bit for host power to control a signal
> named HOST_DRV_VBUS and init at dwc_otg_core_host_init(), but we do not
> using that controller signal, and using a GPIO instead, which may be
> different
> in different board, so we usually enable it in board file.
>
> Let me have a try if we can move it to USB driver.
In that case it should be mentioned in the device tree, so you can
perhaps use gpio-regulator.
>
>>
>> In fact it looks like board_usb_init() should move into a driver.
>
>
> We are not using board_usb_init() for usb host now, this function is only
> used
> for usb gadget/udc.
OK I see, that's fine.
BTW the merge window will open soon so please send any other patches
you have planned for the next release.
Regards,
Simon
^ permalink raw reply
* [U-Boot] [PATCHv2 03/15] dm: pci: remove pci_bus_to_hose(0) calling
From: Simon Glass @ 2016-11-14 20:44 UTC (permalink / raw)
To: u-boot
In-Reply-To: <DB6PR0401MB2549FCA4FB536383BD17EAC684BC0@DB6PR0401MB2549.eurprd04.prod.outlook.com>
Hi,
On 14 November 2016 at 00:22, Z.Q. Hou <zhiqiang.hou@nxp.com> wrote:
> Hi Simon,
>
> Thanks for your comments!
>
>> -----Original Message-----
>> From: sjg at google.com [mailto:sjg at google.com] On Behalf Of Simon Glass
>> Sent: 2016?11?12? 0:18
>> To: Z.Q. Hou <zhiqiang.hou@nxp.com>
>> Cc: U-Boot Mailing List <u-boot@lists.denx.de>; Albert ARIBAUD
>> <albert.u.boot@aribaud.net>; Prabhakar Kushwaha
>> <prabhakar.kushwaha@nxp.com>; Huan Wang-B18965
>> <alison.wang@freescale.com>; Sumit Garg <sumit.garg@nxp.com>; Ruchika
>> Gupta <ruchika.gupta@nxp.com>; Saksham Jain
>> <saksham.jain@nxp.freescale.com>; york sun <york.sun@nxp.com>; M.H. Lian
>> <minghuan.lian@nxp.com>; Bin Meng <bmeng.cn@gmail.com>; Mingkai Hu
>> <mingkai.hu@nxp.com>
>> Subject: Re: [PATCHv2 03/15] dm: pci: remove pci_bus_to_hose(0) calling
>>
>> Hi,
>>
>> On 10 November 2016 at 03:58, Zhiqiang Hou <Zhiqiang.Hou@nxp.com>
>> wrote:
>> > From: Minghuan Lian <Minghuan.Lian@nxp.com>
>> >
>> > There may be multiple PCIe controllers in a SoC.
>> > It is not correct that always calling pci_bus_to_hose(0) to get the
>> > first PCIe controller for the PCIe device connected other controllers.
>> > We just remove this calling because hose always point the correct PCIe
>> > controller.
>> >
>> > Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
>> > Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>> > ---
>> > V2:
>> > - No change
>> >
>> > drivers/pci/pci_common.c | 10 ----------
>> > 1 file changed, 10 deletions(-)
>>
>> So is 'hose' always a root PCI controller now? If so, can you comment these in
>> the header? I'm a bit confused by this
>
> Yes, the patch 02 of this patchset statement that the function pci_bus_to_hose() will return the root pci controller.
> And will add the comment for the function.
>
>>
>> We should perhaps move the regions[] array into its own struct separate from
>> pci_controller.
>
> Could you let this patch set in first? Because I think this is a big task, and so far we have no effort to do that.
Yes - please add a comment as above, and a TODO for yourself.
Reviewed-by: Simon Glass <sjg@chromium.org>
>
>>
>> >
>> > diff --git a/drivers/pci/pci_common.c b/drivers/pci/pci_common.c index
>> > 1755914..448e814 100644
>> > --- a/drivers/pci/pci_common.c
>> > +++ b/drivers/pci/pci_common.c
>> > @@ -181,11 +181,6 @@ phys_addr_t pci_hose_bus_to_phys(struct
>> pci_controller *hose,
>> > return phys_addr;
>> > }
>> >
>> > -#ifdef CONFIG_DM_PCI
>> > - /* The root controller has the region information */
>> > - hose = pci_bus_to_hose(0);
>> > -#endif
>> > -
>> > /*
>> > * if PCI_REGION_MEM is set we do a two pass search with
>> preference
>> > * on matches that don't have PCI_REGION_SYS_MEMORY set
>> @@
>> > -248,11 +243,6 @@ pci_addr_t pci_hose_phys_to_bus(struct pci_controller
>> *hose,
>> > return bus_addr;
>> > }
>> >
>> > -#ifdef CONFIG_DM_PCI
>> > - /* The root controller has the region information */
>> > - hose = pci_bus_to_hose(0);
>> > -#endif
>> > -
>> > /*
>> > * if PCI_REGION_MEM is set we do a two pass search with
>> preference
>> > * on matches that don't have PCI_REGION_SYS_MEMORY set
>> > --
>> > 2.1.0.27.g96db324
>> >
>
> Thanks,
> Zhiqiang
Regards,
Simon
^ permalink raw reply
* [U-Boot] [PATCH] fastboot: simplify the Kconfig logic
From: Simon Glass @ 2016-11-14 20:44 UTC (permalink / raw)
To: u-boot
In-Reply-To: <1479072373-7307-1-git-send-email-yann.morin.1998@free.fr>
+Tom
On 13 November 2016 at 14:26, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> Currently, the fastboot item in menuconfig is a comment followed by a
> boolean option withan empty prompt, followed by a menu:
>
> *** FASTBOOT ***
> [*]
> Fastboot support --->
>
> This is not "nice-looking" at all...
>
> Change the logic to make the boolean option a "menuconfig" rather than a
> mere "config", so that all dependent options gets groupped under a menu.
> The layout is now:
>
> *** FASTBOOT ***
> [*] Fastboot support --->
>
> Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
> Cc: Simon Glass <sjg@chromium.org>
> ---
> cmd/fastboot/Kconfig | 9 ++++-----
> 1 file changed, 4 insertions(+), 5 deletions(-)
Reviewed-by: Simon Glass <sjg@chromium.org>
Tested-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply
* [U-Boot] [PATCH] usb: check udev before dereferencing
From: Simon Glass @ 2016-11-14 20:44 UTC (permalink / raw)
To: u-boot
In-Reply-To: <a6fef258-c3ea-f06f-2f14-550ede9d8d3e@denx.de>
Hi,
On 12 November 2016 at 11:17, Marek Vasut <marex@denx.de> wrote:
> On 11/12/2016 07:10 PM, Anatolij Gustschin wrote:
>> On Sat, 12 Nov 2016 10:36:42 +0100
>> Marek Vasut marex at denx.de wrote:
>> ...
>>>> udev = dev_get_parent_priv(child);
>>>> + if (!udev)
>>>> + continue;
>>>
>>> I don't quite understand the problem from the patch description, but
>>> shouldn't all the return values from dev_get_parent_priv() be checked
>>> this way , not just these two ?
>>
>> The problem is that when dereferencing NULL udev we later access
>> some random address (e.g. when accessing dev->dev->parent in
>> usb_show_tree_graph()). dev->dev pointer is random DRAM data there,
>> when dereferencing it, data abort happens when random address
>> is outside of valid address range.
>
> I mean, I understand that udev can be NULL and we don't check it. But is
> udev == NULL an expected possibility ? And if so, when does such thing
> happen ?
>
>> Probably we should check elsewhere, at least where it might
>> return NULL.
>
> OK
>
>>>
>>> Why does dev_get_parent_priv() return NULL here ?
>>
>> it returns NULL because the dev->parent_priv is not allocated for
>> usb_mass_storage.lun0 device. I do not know the reason why.
>
> That's probably what needs to be fixed , no ?
Yes that seems wrong. There is a check immediately before this:
if (!device_active(child))
continue;
If the device is active, it must have been probed and so must have parent data.
See:
UCLASS_DRIVER(usb) = {
...
.per_child_auto_alloc_size = sizeof(struct usb_device),
Try 'dm tree' to see what the bad USB device is.
>
> Also, we should most likely check all the return values of
> dev_get_parent_priv() in cmd/usb.c, not just these two.
Regards,
Simon
^ permalink raw reply
* [U-Boot] [PATCH v2 2/3] spl: dfu: move DFU Kconfig to SPL Kconfig
From: Simon Glass @ 2016-11-14 20:44 UTC (permalink / raw)
To: u-boot
In-Reply-To: <20161112191308.22185-3-stefan@agner.ch>
On 12 November 2016 at 12:13, Stefan Agner <stefan@agner.ch> wrote:
> From: Stefan Agner <stefan.agner@toradex.com>
>
> The DFU Kconfig menu entries should be part of the SPL
> Kconfig file. Also avoid using the top level Makefile by
> moving the config dependent build artifacts to the driver/
> and driver/usb/gadget/ Makfiles.
>
> With that, DFU can be built again in SPL if
> CONFIG_SPL_DFU_SUPPORT is enabled.
>
> Fixes: 6ad6102246d8 ("usb:gadget: Disallow DFU in SPL for now")
>
> Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
>
> ---
> Tom, I checked size for am335x_evm_usbspl_defconfig, it stays
> fine with this patch.
>
> Changes in v2:
> - Leave DWC3 config in top level SPL Makefile (as U-Boot does)
>
> Kconfig | 27 ---------------------------
> common/spl/Kconfig | 26 ++++++++++++++++++++++++++
> drivers/Makefile | 3 +++
> drivers/usb/gadget/Makefile | 8 ++++++--
> include/configs/dra7xx_evm.h | 1 -
> scripts/Makefile.spl | 3 ---
> 6 files changed, 35 insertions(+), 33 deletions(-)
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply
* [U-Boot] [PATCH v2 1/3] spl: add RAM boot device only if it is actually defined
From: Simon Glass @ 2016-11-14 20:44 UTC (permalink / raw)
To: u-boot
In-Reply-To: <20161112191308.22185-2-stefan@agner.ch>
Hi Stefan,
On 12 November 2016 at 12:13, Stefan Agner <stefan@agner.ch> wrote:
> From: Stefan Agner <stefan.agner@toradex.com>
>
> Some devices (e.g. dra7xx) support loading to RAM using DFU without
> having direct boot from RAM support. Make sure the linker list
> does not contain BOOT_DEVICE_RAM if CONFIG_SPL_RAM_SUPPORT is not
> enabled.
>
> Fixes: 98136b2f26fa ("spl: Convert spl_ram_load_image() to use linker list")
>
> Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
> ---
>
> Changes in v2:
> - Use CONFIG_SPL_RAM_SUPPORT to descide whether to compile the
> function in first place.
>
> common/spl/spl.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
Instead of this, how about moving it into its own file and putting
that condition in the Makefile?
Regards,
Simon
^ permalink raw reply
* Re: [PATCH kvm-unit-tests v2 11/17] pci: provide pci_enable_defaults()
From: Peter Xu @ 2016-11-14 20:42 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, rkrcmar, agordeev, jan.kiszka, pbonzini
In-Reply-To: <20161110193342.yc3rv5grgfo26knu@hawk.localdomain>
On Thu, Nov 10, 2016 at 08:33:42PM +0100, Andrew Jones wrote:
> On Wed, Nov 09, 2016 at 10:10:18AM -0500, Peter Xu wrote:
> > Provide a function to do most of the common PCI init work.
> >
> > Suggested-by: Andrew Jones <drjones@redhat.com>
> > Signed-off-by: Peter Xu <peterx@redhat.com>
> > ---
> > lib/pci.c | 8 ++++++++
> > lib/pci.h | 1 +
> > 2 files changed, 9 insertions(+)
> >
> > diff --git a/lib/pci.c b/lib/pci.c
> > index fd17ea5..971f02e 100644
> > --- a/lib/pci.c
> > +++ b/lib/pci.c
> > @@ -249,3 +249,11 @@ void pci_scan_bars(struct pci_dev *dev)
> > dev->bar[i] = pci_bar_get_addr(dev, i);
> > }
> > }
> > +
> > +int pci_enable_defaults(struct pci_dev *dev)
> > +{
> > + pci_scan_bars(dev);
> > + /* Enable device DMA operations */
> > + pci_cmd_set_clr(dev, PCI_COMMAND_MASTER, 0);
> > + return 0;
>
> Shouldn't this be a void function that just asserts on
> any errors it detects? I'm not sure why we're [currently
> unconditionally] returning zero.
This is my intention since I think this function might grow in the
future with lots of stuffs inside, and this function will need a
return code as long as any one of the future small functions will
return an error. However that's really not a strong reason to have
it... will remove it for your r-b. :-)
Thanks,
-- peterx
^ permalink raw reply
* Re: [PATCH v3] mm, thp: propagation of conditional compilation in khugepaged.c
From: Kirill A. Shutemov @ 2016-11-14 20:42 UTC (permalink / raw)
To: Jérémy Lefaure; +Cc: Andrew Morton, Kirill A. Shutemov, linux-mm
In-Reply-To: <20161114203448.24197-1-jeremy.lefaure@lse.epita.fr>
On Mon, Nov 14, 2016 at 03:34:48PM -0500, Jeremy Lefaure wrote:
> Commit b46e756f5e47 ("thp: extract khugepaged from mm/huge_memory.c")
> moved code from huge_memory.c to khugepaged.c. Some of this code should
> be compiled only when CONFIG_SYSFS is enabled but the condition around
> this code was not moved into khugepaged.c. The result is a compilation
> error when CONFIG_SYSFS is disabled:
>
> mm/built-in.o: In function `khugepaged_defrag_store':
> khugepaged.c:(.text+0x2d095): undefined reference to
> `single_hugepage_flag_store'
> mm/built-in.o: In function `khugepaged_defrag_show':
> khugepaged.c:(.text+0x2d0ab): undefined reference to
> `single_hugepage_flag_show'
>
> This commit adds the #ifdef CONFIG_SYSFS around the code related to
> sysfs.
>
> Signed-off-by: Jeremy Lefaure <jeremy.lefaure@lse.epita.fr>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
--
Kirill A. Shutemov
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [RFC] Split up policycoreutils
From: Jason Zaman @ 2016-11-14 20:41 UTC (permalink / raw)
To: Stephen Smalley; +Cc: SELinux
In-Reply-To: <d1be7324-fea8-1044-b3a0-64e590f38f43@tycho.nsa.gov>
On Tue, Nov 08, 2016 at 02:42:31PM -0500, Stephen Smalley wrote:
> On 10/31/2016 02:05 PM, Stephen Smalley wrote:
> > On 10/21/2016 01:47 PM, Stephen Smalley wrote:
> >> Hi,
> >>
> >> policycoreutils started life as a small set of utilities that were
> >> necessary or at least widely used in production on a SELinux system.
> >> Over time though it has grown to include many optional components, and
> >> even within a given subdirectory (e.g. sepolicy) there seem to be a
> >> number of components that should be optional (e.g. the dbus service).
> >> I'd like to propose that we move a number of components out of
> >> policycoreutils into their own top-level subdirectory (possibly grouping
> >> some of the related ones together).
> >>
> >> Some possible components to move and the rationale for doing so include:
> >>
> >> - gui: not required for operation. Unsure if this is even used outside
> >> of Fedora, or how widely it is used within Fedora compared to the
> >> command line tools. Packaged separately by Fedora as part of
> >> policycoreutils-gui.
> >>
> >> - mcstrans: not required for operation outside of MLS environments (and
> >> even there, only if using that label encoding functionality), not built
> >> by default even upstream (omitted from policycoreutils/Makefile).
> >> Packaged separately in Fedora as mcstrans.
> >>
> >> - restorecond: not required for operation, adds dbus and glib
> >> dependencies, largely obsoleted by name-based type transition support in
> >> the kernel. Packaged separately in Fedora as policycoreutils-restorecond.
> >>
> >> - sandbox: not required for basic operation of SELinux. Packaged
> >> separately by Fedora as policycoreutils-sandbox.
> >> restorecond
> >> - semodule_deps/expand/link: developer tools only, not required for
> >> operation, unlike semodule. Packaged separately by Fedora as part of
> >> policycoreutils-devel.
> >>
> >> - sepolicy/{org.selinux*,selinux_client.py,selinux_server.py}: D-BUS
> >> service for managing SELinux, not required for basic operation, not
> >> desirable in high security environments. Packaged separately by Fedora
> >> as part of policycoreutils-gui. Could perhaps be combined with the gui
> >> above, although I think they are logically distinct.
> >>
> >> We could of course go further, but those seem to be the most obvious
> >> candidates.
> >>
> >> Thoughts?
> >
> > For discussion purposes, I've pushed a splitpolicycoreutils branch that
> > moves the above components and others identified in the discussion
> > thread, and makes it easy to omit the non-core components from the
> > build. Take a look and see what you think. Known issues:
> >
> > - I did not deal with splitting the policycoreutils/po files and moving
> > them around. Not sure what the best way to handle that is.
> >
> > - python/sepolicy likely needs further rearrangement. I am unclear on
> > the purpose/use of the desktop file and pixmaps; if those are only for
> > the gui, then they can be moved to gui/, but I don't understand why they
> > are called sepolicy* or located here. Also, should
> > python/sepolicy/sepolicy/sedbus.py be moved over to dbus/ or stay here?
> > Dan?
> >
> > - dbus/selinux_client.py (formerly
> > policycoreutils/sepolicy/selinux_client.py) seems like leftover testing
> > cruft. Remove?
> >
> > - restorecond presently reuses source code directly from setfiles, so
> > building it as a separate package may be a nuisance. OTOH, I'm not
> > entirely clear on whether restorecond needs to be kept around at all
> > anymore?
> >
> > - policycoreutils/sepolgen-ifgen contains a single C program,
> > sepolgen-ifgen-attr-helper, that is only used by
> > python/audit2allow/sepolgen-ifgen. Any reason to not just coalesce it
> > into python/audit2allow even though it is not python itself?
> >
> > - After the restructuring, the only script left in policycoreutils is
> > fixfiles. Technically, that's not required for production either as one
> > can always just run setfiles or restorecon directly, but distros seem to
> > rely on it. Is it worth moving just to free policycoreutils of any bash
> > dependencies, and if so, where?
> >
> > - I moved policycoreutils/semodule_{deps,expand,link} into a new
> > semodule-utils directory. This might however be slightly confusing
> > since semodule and semodule_package remain in policycoreutils since they
> > are required and not merely for developers. Feel free to suggest
> > another name or structure. Actually, I guess semodule_package might be
> > optional now with CIL, so perhaps that one can be moved too.
>
> I've made further changes on the splitpolicycoreutils branch based on
> the discussion (as well as rebasing it on latest master). This is a
> call for final comments or objections before merging it to master. With
> the current branch, we will have the following source tar files in a
> release:
>
> Unchanged:
> * libsepol
> * libselinux
> * libsemanage
> * checkpolicy
> * secilc
>
> Modified or new:
> * policycoreutils (containing only hll, load_policy, newrole, run_init,
> scripts/fixfiles, secon, semodule, sestatus, setfiles, setsebool)
> * mcstrans
> * restorecond
> * semodule-utils (containing semodule_package, semodule_link,
> semodule_expand, semodule_deps)
> * selinux-dbus (containing org.selinux DBus configuration and python files)
> - selinux-gui (containing system-config-selinux aka selinux polgengui)
> - selinux-python (containing audit2allow, including its
> sepolgen-ifgen-attr-helper helper program, chcat, semanage, sepolgen,
> sepolicy)
> - selinux-sandbox (containing sandbox)
>
> No longer separate:
> * sepolgen (moved inside of selinux-python)
These look pretty good to me. I have written most of the ebuilds for
gentoo for these new packages but have not committed to the tree yet.
There are a couple issues:
1) What is the license for each of the tarballs? there is no license or
COPYING file in the dirs.
2) even tho i fixed up a lot of it so shouldnt be, I am *super* confused
about sepolicy vs sepolgen. there are like 4 separate dirs with those
names and the sepolicy Makefile makes a symlink for sepolgen. And then
there is the gui and the non-gui part of them. python/sepolicy/* should
hopefully die soon as things fully move over to setools4. should gui/ be
called system-config-selinux? also is it a redhatism or does it also
apply to other distros?
3) The deps of each of the bits is somewhat complicated to figure out.
semodule-utils looks like it only needs libsepol and libselinux and the
others look like they need most of the others? The makefile just builds
them in order but i'd like to specify more accurate deps in the gentoo
packages (especially external deps for each package) so they get
(re)built as required as things update.
Also which of these are required to build refpolicy? the docs on that
may need updating later too.
4) mcstrans fails to build on my laptop, i'll send patches later. I
might have stricter warnings on or something.
5) in python/sepolicy/Makefile:
override CFLAGS += -I$(PREFIX)/include -DPACKAGE="policycoreutils"
should that be something instead of policycoreutils now?
6) we have a policycoreutils-extra thats been floating around as part of
policycoreutils in gentoo. Mainly has rlpkg and selocal. After this
split is as good a time as any to cleanup and upstream them.
7) I just noticed when looking through different Makefiles that some
variables default to different things. I'll send patches for this too
later once its merged in. Its nothing huge just better to be the same.
> Note that the release script will add the selinux- prefix for dbus, gui,
> python, and sandbox when generating the source tarballs so that they
> have unique names suitable for source packages.
This makes sense but I wonder if the name prefix is going to be annoying
when we end up needing to backport a patch on a release since the paths
would be different. But then again we've always had to edit them since
they are one level down so I dont think I mind this minor extra bit too.
-- Jason
^ permalink raw reply
* [CI 10/10] drm/i915/scheduler: Boost priorities for flips
From: Chris Wilson @ 2016-11-14 20:41 UTC (permalink / raw)
To: intel-gfx
In-Reply-To: <20161114204105.29171-1-chris@chris-wilson.co.uk>
Boost the priority of any rendering required to show the next pageflip
as we want to avoid missing the vblank by being delayed by invisible
workload. We prioritise avoiding jank and jitter in the GUI over
starving background tasks.
v2: Descend dma_fence_array when boosting priorities.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 5 +++
drivers/gpu/drm/i915/i915_gem.c | 65 ++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_display.c | 2 ++
3 files changed, 72 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index fa8ee8738e7c..4e7148a3ee8b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3093,6 +3093,11 @@ int i915_gem_object_wait(struct drm_i915_gem_object *obj,
unsigned int flags,
long timeout,
struct intel_rps_client *rps);
+int i915_gem_object_wait_priority(struct drm_i915_gem_object *obj,
+ unsigned int flags,
+ int priority);
+#define I915_PRIORITY_DISPLAY I915_PRIORITY_MAX
+
int __must_check
i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj,
bool write);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 7a43f2a73552..3fb5e66e4d65 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -34,6 +34,7 @@
#include "intel_drv.h"
#include "intel_frontbuffer.h"
#include "intel_mocs.h"
+#include <linux/dma-fence-array.h>
#include <linux/reservation.h>
#include <linux/shmem_fs.h>
#include <linux/slab.h>
@@ -434,6 +435,70 @@ i915_gem_object_wait_reservation(struct reservation_object *resv,
return timeout;
}
+static void __fence_set_priority(struct dma_fence *fence, int prio)
+{
+ struct drm_i915_gem_request *rq;
+ struct intel_engine_cs *engine;
+
+ if (!dma_fence_is_i915(fence))
+ return;
+
+ rq = to_request(fence);
+ engine = rq->engine;
+ if (!engine->schedule)
+ return;
+
+ engine->schedule(rq, prio);
+}
+
+static void fence_set_priority(struct dma_fence *fence, int prio)
+{
+ /* Recurse once into a fence-array */
+ if (dma_fence_is_array(fence)) {
+ struct dma_fence_array *array = to_dma_fence_array(fence);
+ int i;
+
+ for (i = 0; i < array->num_fences; i++)
+ __fence_set_priority(array->fences[i], prio);
+ } else {
+ __fence_set_priority(fence, prio);
+ }
+}
+
+int
+i915_gem_object_wait_priority(struct drm_i915_gem_object *obj,
+ unsigned int flags,
+ int prio)
+{
+ struct dma_fence *excl;
+
+ if (flags & I915_WAIT_ALL) {
+ struct dma_fence **shared;
+ unsigned int count, i;
+ int ret;
+
+ ret = reservation_object_get_fences_rcu(obj->resv,
+ &excl, &count, &shared);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < count; i++) {
+ fence_set_priority(shared[i], prio);
+ dma_fence_put(shared[i]);
+ }
+
+ kfree(shared);
+ } else {
+ excl = reservation_object_get_excl_rcu(obj->resv);
+ }
+
+ if (excl) {
+ fence_set_priority(excl, prio);
+ dma_fence_put(excl);
+ }
+ return 0;
+}
+
/**
* Waits for rendering to the object to be completed
* @obj: i915 gem object
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 2711c571add2..cb9377de456e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14790,6 +14790,8 @@ intel_prepare_plane_fb(struct drm_plane *plane,
GFP_KERNEL);
if (ret < 0)
return ret;
+
+ i915_gem_object_wait_priority(obj, 0, I915_PRIORITY_DISPLAY);
}
if (plane->type == DRM_PLANE_TYPE_CURSOR &&
--
2.10.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related
* [CI 09/10] drm/i915: Store the execution priority on the context
From: Chris Wilson @ 2016-11-14 20:41 UTC (permalink / raw)
To: intel-gfx
In-Reply-To: <20161114204105.29171-1-chris@chris-wilson.co.uk>
In order to support userspace defining different levels of importance to
different contexts, and in particular the preferred order of execution,
store a priority value on each context. By default, the kernel's
context, which is used for idling and other background tasks, is given
minimum priority (i.e. all user contexts will execute before the kernel).
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/i915_gem_context.c | 1 +
drivers/gpu/drm/i915/i915_gem_request.c | 2 +-
3 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6aad69fe8ccf..fa8ee8738e7c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -936,6 +936,7 @@ struct i915_gem_context {
/* Unique identifier for this context, used by the hw for tracking */
unsigned int hw_id;
u32 user_handle;
+ int priority; /* greater priorities are serviced first */
u32 ggtt_alignment;
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 6dd475735f0a..1f94b8d6d83d 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -476,6 +476,7 @@ int i915_gem_context_init(struct drm_device *dev)
return PTR_ERR(ctx);
}
+ ctx->priority = I915_PRIORITY_MIN; /* lowest priority; idle task */
dev_priv->kernel_context = ctx;
DRM_DEBUG_DRIVER("%s context support initialized\n",
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 13574a1e29b1..b9b5253cf3cd 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -867,7 +867,7 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
* run at the earliest possible convenience.
*/
if (engine->schedule)
- engine->schedule(request, 0);
+ engine->schedule(request, request->ctx->priority);
local_bh_disable();
i915_sw_fence_commit(&request->submit);
--
2.10.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related
* [CI 08/10] drm/i915/scheduler: Execute requests in order of priorities
From: Chris Wilson @ 2016-11-14 20:41 UTC (permalink / raw)
To: intel-gfx
In-Reply-To: <20161114204105.29171-1-chris@chris-wilson.co.uk>
Track the priority of each request and use it to determine the order in
which we submit requests to the hardware via execlists.
The priority of the request is determined by the user (eventually via
the context) but may be overridden at any time by the driver. When we set
the priority of the request, we bump the priority of all of its
dependencies to match - so that a high priority drawing operation is not
stuck behind a background task.
When the request is ready to execute (i.e. we have signaled the submit
fence following completion of all its dependencies, including third
party fences), we put the request into a priority sorted rbtree to be
submitted to the hardware. If the request is higher priority than all
pending requests, it will be submitted on the next context-switch
interrupt as soon as the hardware has completed the current request. We
do not currently preempt any current execution to immediately run a very
high priority request, at least not yet.
One more limitation, is that this is first implementation is for
execlists only so currently limited to gen8/gen9.
v2: Replace recursive priority inheritance bumping with an iterative
depth-first search list.
v3: list_next_entry() for walking lists
v4: Explain how the dfs solves the recursion problem with PI.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
drivers/gpu/drm/i915/i915_debugfs.c | 7 +-
drivers/gpu/drm/i915/i915_gem.c | 3 +-
drivers/gpu/drm/i915/i915_gem_request.c | 5 +
drivers/gpu/drm/i915/i915_gem_request.h | 8 +-
drivers/gpu/drm/i915/i915_guc_submission.c | 1 +
drivers/gpu/drm/i915/intel_engine_cs.c | 3 +-
drivers/gpu/drm/i915/intel_lrc.c | 151 +++++++++++++++++++++++++++--
drivers/gpu/drm/i915/intel_ringbuffer.h | 3 +-
8 files changed, 165 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 03e3c2afbb06..1cc971cb6cb1 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -631,8 +631,9 @@ static void print_request(struct seq_file *m,
struct drm_i915_gem_request *rq,
const char *prefix)
{
- seq_printf(m, "%s%x [%x:%x] @ %d: %s\n", 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);
}
@@ -3216,6 +3217,7 @@ static int i915_engine_info(struct seq_file *m, void *unused)
if (i915.enable_execlists) {
u32 ptr, read, write;
+ struct rb_node *rb;
seq_printf(m, "\tExeclist status: 0x%08x %08x\n",
I915_READ(RING_EXECLIST_STATUS_LO(engine)),
@@ -3255,7 +3257,8 @@ static int i915_engine_info(struct seq_file *m, void *unused)
rcu_read_unlock();
spin_lock_irq(&engine->timeline->lock);
- list_for_each_entry(rq, &engine->execlist_queue, execlist_link) {
+ for (rb = engine->execlist_first; rb; rb = rb_next(rb)) {
+ rq = rb_entry(rb, typeof(*rq), priotree.node);
print_request(m, rq, "\t\tQ ");
}
spin_unlock_irq(&engine->timeline->lock);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index faecce3c4d21..7a43f2a73552 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2721,10 +2721,11 @@ static void i915_gem_cleanup_engine(struct intel_engine_cs *engine)
spin_lock_irqsave(&engine->timeline->lock, flags);
- INIT_LIST_HEAD(&engine->execlist_queue);
i915_gem_request_put(engine->execlist_port[0].request);
i915_gem_request_put(engine->execlist_port[1].request);
memset(engine->execlist_port, 0, sizeof(engine->execlist_port));
+ engine->execlist_queue = RB_ROOT;
+ engine->execlist_first = NULL;
spin_unlock_irqrestore(&engine->timeline->lock, flags);
}
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 78c87d94d205..13574a1e29b1 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -132,6 +132,7 @@ __i915_priotree_add_dependency(struct i915_priotree *pt,
struct i915_dependency *dep,
unsigned long flags)
{
+ INIT_LIST_HEAD(&dep->dfs_link);
list_add(&dep->wait_link, &signal->waiters_list);
list_add(&dep->signal_link, &pt->signalers_list);
dep->signaler = signal;
@@ -158,6 +159,8 @@ i915_priotree_fini(struct drm_i915_private *i915, struct i915_priotree *pt)
{
struct i915_dependency *dep, *next;
+ GEM_BUG_ON(!RB_EMPTY_NODE(&pt->node));
+
/* Everyone we depended upon (the fences we wait to be signaled)
* should retire before us and remove themselves from our list.
* However, retirement is run independently on each timeline and
@@ -182,6 +185,8 @@ i915_priotree_init(struct i915_priotree *pt)
{
INIT_LIST_HEAD(&pt->signalers_list);
INIT_LIST_HEAD(&pt->waiters_list);
+ RB_CLEAR_NODE(&pt->node);
+ pt->priority = INT_MIN;
}
void i915_gem_retire_noop(struct i915_gem_active *active,
diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h
index 943c39d2a62a..e2b077df2da0 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.h
+++ b/drivers/gpu/drm/i915/i915_gem_request.h
@@ -48,6 +48,7 @@ struct i915_dependency {
struct i915_priotree *signaler;
struct list_head signal_link;
struct list_head wait_link;
+ struct list_head dfs_link;
unsigned long flags;
#define I915_DEPENDENCY_ALLOC BIT(0)
};
@@ -64,6 +65,10 @@ struct i915_dependency {
struct i915_priotree {
struct list_head signalers_list; /* those before us, we depend upon */
struct list_head waiters_list; /* those after us, they depend upon us */
+ struct rb_node node;
+ int priority;
+#define I915_PRIORITY_MAX 1024
+#define I915_PRIORITY_MIN (-I915_PRIORITY_MAX)
};
/**
@@ -194,9 +199,6 @@ struct drm_i915_gem_request {
struct drm_i915_file_private *file_priv;
/** file_priv list entry for this request */
struct list_head client_list;
-
- /** Link in the execlist submission queue, guarded by execlist_lock. */
- struct list_head execlist_link;
};
extern const struct dma_fence_ops i915_fence_ops;
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index 942f5000d372..4462112725ef 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -1532,6 +1532,7 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv)
/* Take over from manual control of ELSP (execlists) */
for_each_engine(engine, dev_priv, id) {
engine->submit_request = i915_guc_submit;
+ engine->schedule = NULL;
/* Replay the current set of previously submitted requests */
list_for_each_entry(request,
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index c9171a058478..3da4d466e332 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -239,7 +239,8 @@ static void intel_engine_init_timeline(struct intel_engine_cs *engine)
*/
void intel_engine_setup_common(struct intel_engine_cs *engine)
{
- INIT_LIST_HEAD(&engine->execlist_queue);
+ engine->execlist_queue = RB_ROOT;
+ engine->execlist_first = NULL;
intel_engine_init_timeline(engine);
intel_engine_init_hangcheck(engine);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index d1aea7462515..2a14ce754268 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -432,9 +432,10 @@ static bool can_merge_ctx(const struct i915_gem_context *prev,
static void execlists_dequeue(struct intel_engine_cs *engine)
{
- struct drm_i915_gem_request *cursor, *last;
+ struct drm_i915_gem_request *last;
struct execlist_port *port = engine->execlist_port;
unsigned long flags;
+ struct rb_node *rb;
bool submit = false;
last = port->request;
@@ -471,7 +472,11 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
*/
spin_lock_irqsave(&engine->timeline->lock, flags);
- list_for_each_entry(cursor, &engine->execlist_queue, execlist_link) {
+ rb = engine->execlist_first;
+ while (rb) {
+ struct drm_i915_gem_request *cursor =
+ rb_entry(rb, typeof(*cursor), priotree.node);
+
/* Can we combine this request with the current port? It has to
* be the same context/ringbuffer and not have any exceptions
* (e.g. GVT saying never to combine contexts).
@@ -503,6 +508,11 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
port++;
}
+ rb = rb_next(rb);
+ rb_erase(&cursor->priotree.node, &engine->execlist_queue);
+ RB_CLEAR_NODE(&cursor->priotree.node);
+ cursor->priotree.priority = INT_MAX;
+
/* We keep the previous context alive until we retire the
* following request. This ensures that any the context object
* is still pinned for any residual writes the HW makes into it
@@ -517,11 +527,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
submit = true;
}
if (submit) {
- /* Decouple all the requests submitted from the queue */
- engine->execlist_queue.next = &cursor->execlist_link;
- cursor->execlist_link.prev = &engine->execlist_queue;
-
i915_gem_request_assign(&port->request, last);
+ engine->execlist_first = rb;
}
spin_unlock_irqrestore(&engine->timeline->lock, flags);
@@ -626,6 +633,32 @@ static void intel_lrc_irq_handler(unsigned long data)
intel_uncore_forcewake_put(dev_priv, engine->fw_domains);
}
+static bool insert_request(struct i915_priotree *pt, struct rb_root *root)
+{
+ struct rb_node **p, *rb;
+ bool first = true;
+
+ /* most positive priority is scheduled first, equal priorities fifo */
+ rb = NULL;
+ p = &root->rb_node;
+ while (*p) {
+ struct i915_priotree *pos;
+
+ rb = *p;
+ pos = rb_entry(rb, typeof(*pos), node);
+ if (pt->priority > pos->priority) {
+ p = &rb->rb_left;
+ } else {
+ p = &rb->rb_right;
+ first = false;
+ }
+ }
+ rb_link_node(&pt->node, rb, p);
+ rb_insert_color(&pt->node, root);
+
+ return first;
+}
+
static void execlists_submit_request(struct drm_i915_gem_request *request)
{
struct intel_engine_cs *engine = request->engine;
@@ -634,13 +667,112 @@ static void execlists_submit_request(struct drm_i915_gem_request *request)
/* Will be called from irq-context when using foreign fences. */
spin_lock_irqsave(&engine->timeline->lock, flags);
- list_add_tail(&request->execlist_link, &engine->execlist_queue);
+ if (insert_request(&request->priotree, &engine->execlist_queue))
+ engine->execlist_first = &request->priotree.node;
if (execlists_elsp_idle(engine))
tasklet_hi_schedule(&engine->irq_tasklet);
spin_unlock_irqrestore(&engine->timeline->lock, flags);
}
+static struct intel_engine_cs *
+pt_lock_engine(struct i915_priotree *pt, struct intel_engine_cs *locked)
+{
+ struct intel_engine_cs *engine;
+
+ engine = container_of(pt,
+ struct drm_i915_gem_request,
+ priotree)->engine;
+ if (engine != locked) {
+ if (locked)
+ spin_unlock_irq(&locked->timeline->lock);
+ spin_lock_irq(&engine->timeline->lock);
+ }
+
+ return engine;
+}
+
+static void execlists_schedule(struct drm_i915_gem_request *request, int prio)
+{
+ struct intel_engine_cs *engine = NULL;
+ struct i915_dependency *dep, *p;
+ struct i915_dependency stack;
+ LIST_HEAD(dfs);
+
+ if (prio <= READ_ONCE(request->priotree.priority))
+ return;
+
+ /* Need BKL in order to use the temporary link inside i915_dependency */
+ lockdep_assert_held(&request->i915->drm.struct_mutex);
+
+ stack.signaler = &request->priotree;
+ list_add(&stack.dfs_link, &dfs);
+
+ /* Recursively bump all dependent priorities to match the new request.
+ *
+ * A naive approach would be to use recursion:
+ * static void update_priorities(struct i915_priotree *pt, prio) {
+ * list_for_each_entry(dep, &pt->signalers_list, signal_link)
+ * update_priorities(dep->signal, prio)
+ * insert_request(pt);
+ * }
+ * but that may have unlimited recursion depth and so runs a very
+ * real risk of overunning the kernel stack. Instead, we build
+ * a flat list of all dependencies starting with the current request.
+ * As we walk the list of dependencies, we add all of its dependencies
+ * to the end of the list (this may include an already visited
+ * request) and continue to walk onwards onto the new dependencies. The
+ * end result is a topological list of requests in reverse order, the
+ * last element in the list is the request we must execute first.
+ */
+ list_for_each_entry_safe(dep, p, &dfs, dfs_link) {
+ struct i915_priotree *pt = dep->signaler;
+
+ list_for_each_entry(p, &pt->signalers_list, signal_link)
+ if (prio > READ_ONCE(p->signaler->priority))
+ list_move_tail(&p->dfs_link, &dfs);
+
+ p = list_next_entry(dep, dfs_link);
+ if (!RB_EMPTY_NODE(&pt->node))
+ continue;
+
+ engine = pt_lock_engine(pt, engine);
+
+ /* If it is not already in the rbtree, we can update the
+ * priority inplace and skip over it (and its dependencies)
+ * if it is referenced *again* as we descend the dfs.
+ */
+ if (prio > pt->priority && RB_EMPTY_NODE(&pt->node)) {
+ pt->priority = prio;
+ list_del_init(&dep->dfs_link);
+ }
+ }
+
+ /* Fifo and depth-first replacement ensure our deps execute before us */
+ list_for_each_entry_safe_reverse(dep, p, &dfs, dfs_link) {
+ struct i915_priotree *pt = dep->signaler;
+
+ INIT_LIST_HEAD(&dep->dfs_link);
+
+ engine = pt_lock_engine(pt, engine);
+
+ if (prio <= pt->priority)
+ continue;
+
+ GEM_BUG_ON(RB_EMPTY_NODE(&pt->node));
+
+ pt->priority = prio;
+ rb_erase(&pt->node, &engine->execlist_queue);
+ if (insert_request(pt, &engine->execlist_queue))
+ engine->execlist_first = &pt->node;
+ }
+
+ if (engine)
+ spin_unlock_irq(&engine->timeline->lock);
+
+ /* XXX Do we need to preempt to make room for us and our deps? */
+}
+
int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request)
{
struct intel_engine_cs *engine = request->engine;
@@ -1677,8 +1809,10 @@ void intel_execlists_enable_submission(struct drm_i915_private *dev_priv)
struct intel_engine_cs *engine;
enum intel_engine_id id;
- for_each_engine(engine, dev_priv, id)
+ for_each_engine(engine, dev_priv, id) {
engine->submit_request = execlists_submit_request;
+ engine->schedule = execlists_schedule;
+ }
}
static void
@@ -1691,6 +1825,7 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine)
engine->emit_breadcrumb = gen8_emit_breadcrumb;
engine->emit_breadcrumb_sz = gen8_emit_breadcrumb_sz;
engine->submit_request = execlists_submit_request;
+ engine->schedule = execlists_schedule;
engine->irq_enable = gen8_logical_ring_enable_irq;
engine->irq_disable = gen8_logical_ring_disable_irq;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index b9583941eb6b..3466b4e77e7c 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -348,7 +348,8 @@ struct intel_engine_cs {
struct drm_i915_gem_request *request;
unsigned int count;
} execlist_port[2];
- struct list_head execlist_queue;
+ struct rb_root execlist_queue;
+ struct rb_node *execlist_first;
unsigned int fw_domains;
bool disable_lite_restore_wa;
bool preempt_wa;
--
2.10.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related
* [CI 07/10] drm/i915/scheduler: Record all dependencies upon request construction
From: Chris Wilson @ 2016-11-14 20:41 UTC (permalink / raw)
To: intel-gfx
In-Reply-To: <20161114204105.29171-1-chris@chris-wilson.co.uk>
The scheduler needs to know the dependencies of each request for the
lifetime of the request, as it may choose to reschedule the requests at
any time and must ensure the dependency tree is not broken. This is in
additional to using the fence to only allow execution after all
dependencies have been completed.
One option was to extend the fence to support the bidirectional
dependency tracking required by the scheduler. However the mismatch in
lifetimes between the submit fence and the request essentially meant
that we had to build a completely separate struct (and we could not
simply reuse the existing waitqueue in the fence for one half of the
dependency tracking). The extra dependency tracking simply did not mesh
well with the fence, and keeping it separate both keeps the fence
implementation simpler and allows us to extend the dependency tracking
into a priority tree (whilst maintaining support for reordering the
tree).
To avoid the additional allocations and list manipulations, the use of
the priotree is disabled when there are no schedulers to use it.
v2: Create a dedicated slab for i915_dependency.
Rename the lists.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/i915_gem.c | 11 +++-
drivers/gpu/drm/i915/i915_gem_request.c | 91 ++++++++++++++++++++++++++++++++-
drivers/gpu/drm/i915/i915_gem_request.h | 33 ++++++++++++
4 files changed, 134 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c4a14de92440..6aad69fe8ccf 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1778,6 +1778,7 @@ struct drm_i915_private {
struct kmem_cache *objects;
struct kmem_cache *vmas;
struct kmem_cache *requests;
+ struct kmem_cache *dependencies;
const struct intel_device_info info;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 9741f1a19649..faecce3c4d21 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4434,12 +4434,18 @@ i915_gem_load_init(struct drm_device *dev)
if (!dev_priv->requests)
goto err_vmas;
+ dev_priv->dependencies = KMEM_CACHE(i915_dependency,
+ SLAB_HWCACHE_ALIGN |
+ SLAB_RECLAIM_ACCOUNT);
+ if (!dev_priv->dependencies)
+ goto err_requests;
+
mutex_lock(&dev_priv->drm.struct_mutex);
INIT_LIST_HEAD(&dev_priv->gt.timelines);
err = i915_gem_timeline_init__global(dev_priv);
mutex_unlock(&dev_priv->drm.struct_mutex);
if (err)
- goto err_requests;
+ goto err_dependencies;
INIT_LIST_HEAD(&dev_priv->context_list);
INIT_WORK(&dev_priv->mm.free_work, __i915_gem_free_work);
@@ -4467,6 +4473,8 @@ i915_gem_load_init(struct drm_device *dev)
return 0;
+err_dependencies:
+ kmem_cache_destroy(dev_priv->dependencies);
err_requests:
kmem_cache_destroy(dev_priv->requests);
err_vmas:
@@ -4483,6 +4491,7 @@ void i915_gem_load_cleanup(struct drm_device *dev)
WARN_ON(!llist_empty(&dev_priv->mm.free_list));
+ kmem_cache_destroy(dev_priv->dependencies);
kmem_cache_destroy(dev_priv->requests);
kmem_cache_destroy(dev_priv->vmas);
kmem_cache_destroy(dev_priv->objects);
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 1118cf48d6f0..78c87d94d205 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -113,6 +113,77 @@ i915_gem_request_remove_from_client(struct drm_i915_gem_request *request)
spin_unlock(&file_priv->mm.lock);
}
+static struct i915_dependency *
+i915_dependency_alloc(struct drm_i915_private *i915)
+{
+ return kmem_cache_alloc(i915->dependencies, GFP_KERNEL);
+}
+
+static void
+i915_dependency_free(struct drm_i915_private *i915,
+ struct i915_dependency *dep)
+{
+ kmem_cache_free(i915->dependencies, dep);
+}
+
+static void
+__i915_priotree_add_dependency(struct i915_priotree *pt,
+ struct i915_priotree *signal,
+ struct i915_dependency *dep,
+ unsigned long flags)
+{
+ list_add(&dep->wait_link, &signal->waiters_list);
+ list_add(&dep->signal_link, &pt->signalers_list);
+ dep->signaler = signal;
+ dep->flags = flags;
+}
+
+static int
+i915_priotree_add_dependency(struct drm_i915_private *i915,
+ struct i915_priotree *pt,
+ struct i915_priotree *signal)
+{
+ struct i915_dependency *dep;
+
+ dep = i915_dependency_alloc(i915);
+ if (!dep)
+ return -ENOMEM;
+
+ __i915_priotree_add_dependency(pt, signal, dep, I915_DEPENDENCY_ALLOC);
+ return 0;
+}
+
+static void
+i915_priotree_fini(struct drm_i915_private *i915, struct i915_priotree *pt)
+{
+ struct i915_dependency *dep, *next;
+
+ /* Everyone we depended upon (the fences we wait to be signaled)
+ * should retire before us and remove themselves from our list.
+ * However, retirement is run independently on each timeline and
+ * so we may be called out-of-order.
+ */
+ list_for_each_entry_safe(dep, next, &pt->signalers_list, signal_link) {
+ list_del(&dep->wait_link);
+ if (dep->flags & I915_DEPENDENCY_ALLOC)
+ i915_dependency_free(i915, dep);
+ }
+
+ /* Remove ourselves from everyone who depends upon us */
+ list_for_each_entry_safe(dep, next, &pt->waiters_list, wait_link) {
+ list_del(&dep->signal_link);
+ if (dep->flags & I915_DEPENDENCY_ALLOC)
+ i915_dependency_free(i915, dep);
+ }
+}
+
+static void
+i915_priotree_init(struct i915_priotree *pt)
+{
+ INIT_LIST_HEAD(&pt->signalers_list);
+ INIT_LIST_HEAD(&pt->waiters_list);
+}
+
void i915_gem_retire_noop(struct i915_gem_active *active,
struct drm_i915_gem_request *request)
{
@@ -182,6 +253,8 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
i915_gem_context_put(request->ctx);
dma_fence_signal(&request->fence);
+
+ i915_priotree_fini(request->i915, &request->priotree);
i915_gem_request_put(request);
}
@@ -467,6 +540,8 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
*/
i915_sw_fence_await_sw_fence(&req->execute, &req->submit, &req->execq);
+ i915_priotree_init(&req->priotree);
+
INIT_LIST_HEAD(&req->active_list);
req->i915 = dev_priv;
req->engine = engine;
@@ -520,6 +595,14 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to,
GEM_BUG_ON(to == from);
+ if (to->engine->schedule) {
+ ret = i915_priotree_add_dependency(to->i915,
+ &to->priotree,
+ &from->priotree);
+ if (ret < 0)
+ return ret;
+ }
+
if (to->timeline == from->timeline)
return 0;
@@ -743,9 +826,15 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
prev = i915_gem_active_raw(&timeline->last_request,
&request->i915->drm.struct_mutex);
- if (prev)
+ if (prev) {
i915_sw_fence_await_sw_fence(&request->submit, &prev->submit,
&request->submitq);
+ if (engine->schedule)
+ __i915_priotree_add_dependency(&request->priotree,
+ &prev->priotree,
+ &request->dep,
+ 0);
+ }
spin_lock_irq(&timeline->lock);
list_add_tail(&request->link, &timeline->requests);
diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h
index 4d2784633d9f..943c39d2a62a 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.h
+++ b/drivers/gpu/drm/i915/i915_gem_request.h
@@ -44,6 +44,28 @@ struct intel_signal_node {
struct intel_wait wait;
};
+struct i915_dependency {
+ struct i915_priotree *signaler;
+ struct list_head signal_link;
+ struct list_head wait_link;
+ unsigned long flags;
+#define I915_DEPENDENCY_ALLOC BIT(0)
+};
+
+/* Requests exist in a complex web of interdependencies. Each request
+ * has to wait for some other request to complete before it is ready to be run
+ * (e.g. we have to wait until the pixels have been rendering into a texture
+ * before we can copy from it). We track the readiness of a request in terms
+ * of fences, but we also need to keep the dependency tree for the lifetime
+ * of the request (beyond the life of an individual fence). We use the tree
+ * at various points to reorder the requests whilst keeping the requests
+ * in order with respect to their various dependencies.
+ */
+struct i915_priotree {
+ struct list_head signalers_list; /* those before us, we depend upon */
+ struct list_head waiters_list; /* those after us, they depend upon us */
+};
+
/**
* Request queue structure.
*
@@ -105,6 +127,17 @@ struct drm_i915_gem_request {
wait_queue_t submitq;
wait_queue_t execq;
+ /* A list of everyone we wait upon, and everyone who waits upon us.
+ * Even though we will not be submitted to the hardware before the
+ * submit fence is signaled (it waits for all external events as well
+ * as our own requests), the scheduler still needs to know the
+ * dependency tree for the lifetime of the request (from execbuf
+ * to retirement), i.e. bidirectional dependency information for the
+ * request not tied to individual fences.
+ */
+ struct i915_priotree priotree;
+ struct i915_dependency dep;
+
u32 global_seqno;
/** GEM sequence number associated with the previous request,
--
2.10.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related
* [CI 06/10] drm/i915/scheduler: Signal the arrival of a new request
From: Chris Wilson @ 2016-11-14 20:41 UTC (permalink / raw)
To: intel-gfx
In-Reply-To: <20161114204105.29171-1-chris@chris-wilson.co.uk>
The start of the scheduler, add a hook into request submission for the
scheduler to see the arrival of new requests and prepare its runqueues.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
drivers/gpu/drm/i915/i915_drv.c | 4 ++++
drivers/gpu/drm/i915/i915_gem_request.c | 13 +++++++++++++
drivers/gpu/drm/i915/intel_engine_cs.c | 3 +++
drivers/gpu/drm/i915/intel_ringbuffer.h | 9 +++++++++
include/uapi/drm/i915_drm.h | 5 +++++
5 files changed, 34 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index a6397f316b30..4f0e56d3b441 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -323,6 +323,10 @@ static int i915_getparam(struct drm_device *dev, void *data,
*/
value = i915_gem_mmap_gtt_version();
break;
+ case I915_PARAM_HAS_SCHEDULER:
+ value = dev_priv->engine[RCS] &&
+ dev_priv->engine[RCS]->schedule;
+ break;
case I915_PARAM_MMAP_VERSION:
/* Remember to bump this if the version changes! */
case I915_PARAM_HAS_GEM:
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 952d2aec5244..1118cf48d6f0 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -762,6 +762,19 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
i915_gem_mark_busy(engine);
+ /* Let the backend know a new request has arrived that may need
+ * to adjust the existing execution schedule due to a high priority
+ * request - i.e. we may want to preempt the current request in order
+ * to run a high priority dependency chain *before* we can execute this
+ * request.
+ *
+ * This is called before the request is ready to run so that we can
+ * decide whether to preempt the entire chain so that it is ready to
+ * run at the earliest possible convenience.
+ */
+ if (engine->schedule)
+ engine->schedule(request, 0);
+
local_bh_disable();
i915_sw_fence_commit(&request->submit);
local_bh_enable(); /* Kick the execlists tasklet if just scheduled */
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index 298f0f95dd3f..c9171a058478 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -102,6 +102,9 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
engine->mmio_base = info->mmio_base;
engine->irq_shift = info->irq_shift;
+ /* Nothing to do here, execute in order of dependencies */
+ engine->schedule = NULL;
+
dev_priv->engine[id] = engine;
return 0;
}
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index e1351870c203..b9583941eb6b 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -267,6 +267,15 @@ struct intel_engine_cs {
*/
void (*submit_request)(struct drm_i915_gem_request *req);
+ /* Call when the priority on a request has changed and it and its
+ * dependencies may need rescheduling. Note the request itself may
+ * not be ready to run!
+ *
+ * Called under the struct_mutex.
+ */
+ void (*schedule)(struct drm_i915_gem_request *request,
+ int priority);
+
/* Some chipsets are not quite as coherent as advertised and need
* an expensive kick to force a true read of the up-to-date seqno.
* However, the up-to-date seqno is not always required and the last
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 03725fe89859..1c12a350eca3 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -389,6 +389,11 @@ typedef struct drm_i915_irq_wait {
#define I915_PARAM_MIN_EU_IN_POOL 39
#define I915_PARAM_MMAP_GTT_VERSION 40
+/* Query whether DRM_I915_GEM_EXECBUFFER2 supports user defined execution
+ * priorities and the driver will attempt to execute batches in priority order.
+ */
+#define I915_PARAM_HAS_SCHEDULER 41
+
typedef struct drm_i915_getparam {
__s32 param;
/*
--
2.10.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related
* [CI 05/10] drm/i915: Remove engine->execlist_lock
From: Chris Wilson @ 2016-11-14 20:41 UTC (permalink / raw)
To: intel-gfx
In-Reply-To: <20161114204105.29171-1-chris@chris-wilson.co.uk>
The execlist_lock is now completely subsumed by the engine->timeline->lock,
and so we can remove the redundant layer of locking.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
drivers/gpu/drm/i915/i915_debugfs.c | 4 ++--
drivers/gpu/drm/i915/i915_gem.c | 8 ++++++--
drivers/gpu/drm/i915/intel_engine_cs.c | 1 -
drivers/gpu/drm/i915/intel_lrc.c | 7 +++----
drivers/gpu/drm/i915/intel_ringbuffer.h | 1 -
5 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index bce38803f45c..03e3c2afbb06 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3254,11 +3254,11 @@ static int i915_engine_info(struct seq_file *m, void *unused)
seq_printf(m, "\t\tELSP[1] idle\n");
rcu_read_unlock();
- spin_lock_irq(&engine->execlist_lock);
+ spin_lock_irq(&engine->timeline->lock);
list_for_each_entry(rq, &engine->execlist_queue, execlist_link) {
print_request(m, rq, "\t\tQ ");
}
- spin_unlock_irq(&engine->execlist_lock);
+ spin_unlock_irq(&engine->timeline->lock);
} else if (INTEL_GEN(dev_priv) > 6) {
seq_printf(m, "\tPP_DIR_BASE: 0x%08x\n",
I915_READ(RING_PP_DIR_BASE(engine)));
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a6ae3efd1d6a..9741f1a19649 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2717,12 +2717,16 @@ static void i915_gem_cleanup_engine(struct intel_engine_cs *engine)
*/
if (i915.enable_execlists) {
- spin_lock(&engine->execlist_lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&engine->timeline->lock, flags);
+
INIT_LIST_HEAD(&engine->execlist_queue);
i915_gem_request_put(engine->execlist_port[0].request);
i915_gem_request_put(engine->execlist_port[1].request);
memset(engine->execlist_port, 0, sizeof(engine->execlist_port));
- spin_unlock(&engine->execlist_lock);
+
+ spin_unlock_irqrestore(&engine->timeline->lock, flags);
}
}
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index 841f8d1e1410..298f0f95dd3f 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -237,7 +237,6 @@ static void intel_engine_init_timeline(struct intel_engine_cs *engine)
void intel_engine_setup_common(struct intel_engine_cs *engine)
{
INIT_LIST_HEAD(&engine->execlist_queue);
- spin_lock_init(&engine->execlist_lock);
intel_engine_init_timeline(engine);
intel_engine_init_hangcheck(engine);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index dca41834dec1..d1aea7462515 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -471,7 +471,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
*/
spin_lock_irqsave(&engine->timeline->lock, flags);
- spin_lock(&engine->execlist_lock);
list_for_each_entry(cursor, &engine->execlist_queue, execlist_link) {
/* Can we combine this request with the current port? It has to
* be the same context/ringbuffer and not have any exceptions
@@ -524,7 +523,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
i915_gem_request_assign(&port->request, last);
}
- spin_unlock(&engine->execlist_lock);
spin_unlock_irqrestore(&engine->timeline->lock, flags);
if (submit)
@@ -633,13 +631,14 @@ static void execlists_submit_request(struct drm_i915_gem_request *request)
struct intel_engine_cs *engine = request->engine;
unsigned long flags;
- spin_lock_irqsave(&engine->execlist_lock, flags);
+ /* Will be called from irq-context when using foreign fences. */
+ spin_lock_irqsave(&engine->timeline->lock, flags);
list_add_tail(&request->execlist_link, &engine->execlist_queue);
if (execlists_elsp_idle(engine))
tasklet_hi_schedule(&engine->irq_tasklet);
- spin_unlock_irqrestore(&engine->execlist_lock, flags);
+ spin_unlock_irqrestore(&engine->timeline->lock, flags);
}
int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index d1a728791ad4..e1351870c203 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -335,7 +335,6 @@ struct intel_engine_cs {
/* Execlists */
struct tasklet_struct irq_tasklet;
- spinlock_t execlist_lock; /* used inside tasklet, use spin_lock_bh */
struct execlist_port {
struct drm_i915_gem_request *request;
unsigned int count;
--
2.10.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related
* [CI 04/10] drm/i915: Defer transfer onto execution timeline to actual hw submission
From: Chris Wilson @ 2016-11-14 20:40 UTC (permalink / raw)
To: intel-gfx
In-Reply-To: <20161114204105.29171-1-chris@chris-wilson.co.uk>
Defer the transfer from the client's timeline onto the execution
timeline from the point of readiness to the point of actual submission.
For example, in execlists, a request is finally submitted to hardware
when the hardware is ready, and only put onto the hardware queue when
the request is ready. By deferring the transfer, we ensure that the
timeline is maintained in retirement order if we decide to queue the
requests onto the hardware in a different order than fifo.
v2: Rebased onto distinct global/user timeline lock classes.
v3: Play with the position of the spin_lock().
v4: Nesting finally resolved with distinct sw_fence lock classes.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
drivers/gpu/drm/i915/i915_gem_request.c | 38 ++++++++++++++++++++----------
drivers/gpu/drm/i915/i915_gem_request.h | 3 +++
drivers/gpu/drm/i915/i915_guc_submission.c | 14 ++++++++++-
drivers/gpu/drm/i915/intel_lrc.c | 23 +++++++++++-------
drivers/gpu/drm/i915/intel_ringbuffer.c | 2 ++
5 files changed, 57 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index d0f6b9f82636..952d2aec5244 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -306,25 +306,16 @@ static u32 timeline_get_seqno(struct i915_gem_timeline *tl)
return atomic_inc_return(&tl->next_seqno);
}
-static int __i915_sw_fence_call
-submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
+void __i915_gem_request_submit(struct drm_i915_gem_request *request)
{
- struct drm_i915_gem_request *request =
- container_of(fence, typeof(*request), submit);
struct intel_engine_cs *engine = request->engine;
struct intel_timeline *timeline;
- unsigned long flags;
u32 seqno;
- if (state != FENCE_COMPLETE)
- return NOTIFY_DONE;
-
/* Transfer from per-context onto the global per-engine timeline */
timeline = engine->timeline;
GEM_BUG_ON(timeline == request->timeline);
-
- /* Will be called from irq-context when using foreign DMA fences */
- spin_lock_irqsave(&timeline->lock, flags);
+ assert_spin_locked(&timeline->lock);
seqno = timeline_get_seqno(timeline->common);
GEM_BUG_ON(!seqno);
@@ -344,15 +335,36 @@ submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
GEM_BUG_ON(!request->global_seqno);
engine->emit_breadcrumb(request,
request->ring->vaddr + request->postfix);
- engine->submit_request(request);
spin_lock(&request->timeline->lock);
list_move_tail(&request->link, &timeline->requests);
spin_unlock(&request->timeline->lock);
i915_sw_fence_commit(&request->execute);
+}
+
+void i915_gem_request_submit(struct drm_i915_gem_request *request)
+{
+ struct intel_engine_cs *engine = request->engine;
+ unsigned long flags;
- spin_unlock_irqrestore(&timeline->lock, flags);
+ /* Will be called from irq-context when using foreign fences. */
+ spin_lock_irqsave(&engine->timeline->lock, flags);
+
+ __i915_gem_request_submit(request);
+
+ spin_unlock_irqrestore(&engine->timeline->lock, flags);
+}
+
+static int __i915_sw_fence_call
+submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
+{
+ if (state == FENCE_COMPLETE) {
+ struct drm_i915_gem_request *request =
+ container_of(fence, typeof(*request), submit);
+
+ request->engine->submit_request(request);
+ }
return NOTIFY_DONE;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h
index 4976039189ea..4d2784633d9f 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.h
+++ b/drivers/gpu/drm/i915/i915_gem_request.h
@@ -232,6 +232,9 @@ void __i915_add_request(struct drm_i915_gem_request *req, bool flush_caches);
#define i915_add_request_no_flush(req) \
__i915_add_request(req, false)
+void __i915_gem_request_submit(struct drm_i915_gem_request *request);
+void i915_gem_request_submit(struct drm_i915_gem_request *request);
+
struct intel_rps_client;
#define NO_WAITBOOST ERR_PTR(-1)
#define IS_RPS_CLIENT(p) (!IS_ERR(p))
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index 666dab7a675a..942f5000d372 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -629,11 +629,23 @@ static int guc_ring_doorbell(struct i915_guc_client *gc)
static void i915_guc_submit(struct drm_i915_gem_request *rq)
{
struct drm_i915_private *dev_priv = rq->i915;
- unsigned int engine_id = rq->engine->id;
+ struct intel_engine_cs *engine = rq->engine;
+ unsigned int engine_id = engine->id;
struct intel_guc *guc = &rq->i915->guc;
struct i915_guc_client *client = guc->execbuf_client;
int b_ret;
+ /* We keep the previous context alive until we retire the following
+ * request. This ensures that any the context object is still pinned
+ * for any residual writes the HW makes into it on the context switch
+ * into the next object following the breadcrumb. Otherwise, we may
+ * retire the context too early.
+ */
+ rq->previous_context = engine->last_context;
+ engine->last_context = rq->ctx;
+
+ i915_gem_request_submit(rq);
+
spin_lock(&client->wq_lock);
guc_wq_item_append(client, rq);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index dde04b7643b1..dca41834dec1 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -434,6 +434,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
{
struct drm_i915_gem_request *cursor, *last;
struct execlist_port *port = engine->execlist_port;
+ unsigned long flags;
bool submit = false;
last = port->request;
@@ -469,6 +470,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
* and context switches) submission.
*/
+ spin_lock_irqsave(&engine->timeline->lock, flags);
spin_lock(&engine->execlist_lock);
list_for_each_entry(cursor, &engine->execlist_queue, execlist_link) {
/* Can we combine this request with the current port? It has to
@@ -501,6 +503,17 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
i915_gem_request_assign(&port->request, last);
port++;
}
+
+ /* We keep the previous context alive until we retire the
+ * following request. This ensures that any the context object
+ * is still pinned for any residual writes the HW makes into it
+ * on the context switch into the next object following the
+ * breadcrumb. Otherwise, we may retire the context too early.
+ */
+ cursor->previous_context = engine->last_context;
+ engine->last_context = cursor->ctx;
+
+ __i915_gem_request_submit(cursor);
last = cursor;
submit = true;
}
@@ -512,6 +525,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
i915_gem_request_assign(&port->request, last);
}
spin_unlock(&engine->execlist_lock);
+ spin_unlock_irqrestore(&engine->timeline->lock, flags);
if (submit)
execlists_submit_ports(engine);
@@ -621,15 +635,6 @@ static void execlists_submit_request(struct drm_i915_gem_request *request)
spin_lock_irqsave(&engine->execlist_lock, flags);
- /* We keep the previous context alive until we retire the following
- * request. This ensures that any the context object is still pinned
- * for any residual writes the HW makes into it on the context switch
- * into the next object following the breadcrumb. Otherwise, we may
- * retire the context too early.
- */
- request->previous_context = engine->last_context;
- engine->last_context = request->ctx;
-
list_add_tail(&request->execlist_link, &engine->execlist_queue);
if (execlists_elsp_idle(engine))
tasklet_hi_schedule(&engine->irq_tasklet);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 700e93d80616..aeb637dc1fdf 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1294,6 +1294,8 @@ static void i9xx_submit_request(struct drm_i915_gem_request *request)
{
struct drm_i915_private *dev_priv = request->i915;
+ i915_gem_request_submit(request);
+
I915_WRITE_TAIL(request->engine, request->tail);
}
--
2.10.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related
* [CI 03/10] drm/i915: Split request submit/execute phase into two
From: Chris Wilson @ 2016-11-14 20:40 UTC (permalink / raw)
To: intel-gfx
In-Reply-To: <20161114204105.29171-1-chris@chris-wilson.co.uk>
In order to support deferred scheduling, we need to differentiate
between when the request is ready to run (i.e. the submit fence is
signaled) and when the request is actually run (a new execute fence).
This is typically split between the request itself wanting to wait upon
others (for which we use the submit fence) and the CPU wanting to wait
upon the request, for which we use the execute fence to be sure the
hardware is ready to signal completion.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
drivers/gpu/drm/i915/i915_gem_request.c | 33 ++++++++++++++++++++++++---------
drivers/gpu/drm/i915/i915_gem_request.h | 15 +++++++++++++++
2 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index f25b537d6e64..d0f6b9f82636 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -350,11 +350,19 @@ submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
list_move_tail(&request->link, &timeline->requests);
spin_unlock(&request->timeline->lock);
+ i915_sw_fence_commit(&request->execute);
+
spin_unlock_irqrestore(&timeline->lock, flags);
return NOTIFY_DONE;
}
+static int __i915_sw_fence_call
+execute_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
+{
+ return NOTIFY_DONE;
+}
+
/**
* i915_gem_request_alloc - allocate a request structure
*
@@ -440,6 +448,12 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
__timeline_get_seqno(req->timeline->common));
i915_sw_fence_init(&req->submit, submit_notify);
+ i915_sw_fence_init(&req->execute, execute_notify);
+ /* Ensure that the execute fence completes after the submit fence -
+ * as we complete the execute fence from within the submit fence
+ * callback, its completion would otherwise be visible first.
+ */
+ i915_sw_fence_await_sw_fence(&req->execute, &req->submit, &req->execq);
INIT_LIST_HEAD(&req->active_list);
req->i915 = dev_priv;
@@ -816,9 +830,9 @@ bool __i915_spin_request(const struct drm_i915_gem_request *req,
}
static long
-__i915_request_wait_for_submit(struct drm_i915_gem_request *request,
- unsigned int flags,
- long timeout)
+__i915_request_wait_for_execute(struct drm_i915_gem_request *request,
+ unsigned int flags,
+ long timeout)
{
const int state = flags & I915_WAIT_INTERRUPTIBLE ?
TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
@@ -830,9 +844,9 @@ __i915_request_wait_for_submit(struct drm_i915_gem_request *request,
add_wait_queue(q, &reset);
do {
- prepare_to_wait(&request->submit.wait, &wait, state);
+ prepare_to_wait(&request->execute.wait, &wait, state);
- if (i915_sw_fence_done(&request->submit))
+ if (i915_sw_fence_done(&request->execute))
break;
if (flags & I915_WAIT_LOCKED &&
@@ -850,7 +864,7 @@ __i915_request_wait_for_submit(struct drm_i915_gem_request *request,
timeout = io_schedule_timeout(timeout);
} while (timeout);
- finish_wait(&request->submit.wait, &wait);
+ finish_wait(&request->execute.wait, &wait);
if (flags & I915_WAIT_LOCKED)
remove_wait_queue(q, &reset);
@@ -902,13 +916,14 @@ long i915_wait_request(struct drm_i915_gem_request *req,
trace_i915_gem_request_wait_begin(req);
- if (!i915_sw_fence_done(&req->submit)) {
- timeout = __i915_request_wait_for_submit(req, flags, timeout);
+ if (!i915_sw_fence_done(&req->execute)) {
+ timeout = __i915_request_wait_for_execute(req, flags, timeout);
if (timeout < 0)
goto complete;
- GEM_BUG_ON(!i915_sw_fence_done(&req->submit));
+ GEM_BUG_ON(!i915_sw_fence_done(&req->execute));
}
+ GEM_BUG_ON(!i915_sw_fence_done(&req->submit));
GEM_BUG_ON(!req->global_seqno);
/* Optimistic short spin before touching IRQs */
diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h
index a56559e3b034..4976039189ea 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.h
+++ b/drivers/gpu/drm/i915/i915_gem_request.h
@@ -87,8 +87,23 @@ struct drm_i915_gem_request {
struct intel_timeline *timeline;
struct intel_signal_node signaling;
+ /* Fences for the various phases in the request's lifetime.
+ *
+ * The submit fence is used to await upon all of the request's
+ * dependencies. When it is signaled, the request is ready to run.
+ * It is used by the driver to then queue the request for execution.
+ *
+ * The execute fence is used to signal when the request has been
+ * sent to hardware.
+ *
+ * It is illegal for the submit fence of one request to wait upon the
+ * execute fence of an earlier request. It should be sufficient to
+ * wait upon the submit fence of the earlier request.
+ */
struct i915_sw_fence submit;
+ struct i915_sw_fence execute;
wait_queue_t submitq;
+ wait_queue_t execq;
u32 global_seqno;
--
2.10.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related
* [CI 02/10] drm/i915: Create distinct lockclasses for execution vs user timelines
From: Chris Wilson @ 2016-11-14 20:40 UTC (permalink / raw)
To: intel-gfx
In-Reply-To: <20161114204105.29171-1-chris@chris-wilson.co.uk>
In order to simplify the lockdep annotation, as they become more complex
in the future with deferred execution and multiple paths through the
same functions, create a separate lockclass for the user timeline and
the hardware execution timeline.
We should only ever be locking the user timeline and the execution
timeline in parallel so we only need to create two lock classes, rather
than a separate class for every timeline.
v2: Rename the lock classes to be more consistent with other lockdep.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
drivers/gpu/drm/i915/i915_gem.c | 4 +---
drivers/gpu/drm/i915/i915_gem_request.c | 2 +-
drivers/gpu/drm/i915/i915_gem_timeline.c | 33 ++++++++++++++++++++++++++++----
drivers/gpu/drm/i915/i915_gem_timeline.h | 1 +
4 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index ed4465d22dde..a6ae3efd1d6a 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4432,9 +4432,7 @@ i915_gem_load_init(struct drm_device *dev)
mutex_lock(&dev_priv->drm.struct_mutex);
INIT_LIST_HEAD(&dev_priv->gt.timelines);
- err = i915_gem_timeline_init(dev_priv,
- &dev_priv->gt.global_timeline,
- "[execution]");
+ err = i915_gem_timeline_init__global(dev_priv);
mutex_unlock(&dev_priv->drm.struct_mutex);
if (err)
goto err_requests;
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 5050464c5401..f25b537d6e64 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -346,7 +346,7 @@ submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
request->ring->vaddr + request->postfix);
engine->submit_request(request);
- spin_lock_nested(&request->timeline->lock, SINGLE_DEPTH_NESTING);
+ spin_lock(&request->timeline->lock);
list_move_tail(&request->link, &timeline->requests);
spin_unlock(&request->timeline->lock);
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.c b/drivers/gpu/drm/i915/i915_gem_timeline.c
index fc8f13a79f8f..bf8a471b61e6 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.c
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.c
@@ -24,9 +24,11 @@
#include "i915_drv.h"
-int i915_gem_timeline_init(struct drm_i915_private *i915,
- struct i915_gem_timeline *timeline,
- const char *name)
+static int __i915_gem_timeline_init(struct drm_i915_private *i915,
+ struct i915_gem_timeline *timeline,
+ const char *name,
+ struct lock_class_key *lockclass,
+ const char *lockname)
{
unsigned int i;
u64 fences;
@@ -47,8 +49,11 @@ int i915_gem_timeline_init(struct drm_i915_private *i915,
tl->fence_context = fences++;
tl->common = timeline;
-
+#ifdef CONFIG_DEBUG_SPINLOCK
+ __raw_spin_lock_init(&tl->lock.rlock, lockname, lockclass);
+#else
spin_lock_init(&tl->lock);
+#endif
init_request_active(&tl->last_request, NULL);
INIT_LIST_HEAD(&tl->requests);
}
@@ -56,6 +61,26 @@ int i915_gem_timeline_init(struct drm_i915_private *i915,
return 0;
}
+int i915_gem_timeline_init(struct drm_i915_private *i915,
+ struct i915_gem_timeline *timeline,
+ const char *name)
+{
+ static struct lock_class_key class;
+
+ return __i915_gem_timeline_init(i915, timeline, name,
+ &class, "&timeline->lock");
+}
+
+int i915_gem_timeline_init__global(struct drm_i915_private *i915)
+{
+ static struct lock_class_key class;
+
+ return __i915_gem_timeline_init(i915,
+ &i915->gt.global_timeline,
+ "[execution]",
+ &class, "&global_timeline->lock");
+}
+
void i915_gem_timeline_fini(struct i915_gem_timeline *tl)
{
lockdep_assert_held(&tl->i915->drm.struct_mutex);
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_gem_timeline.h
index f2bf7b1d49a1..98d99a62b4ae 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.h
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.h
@@ -67,6 +67,7 @@ struct i915_gem_timeline {
int i915_gem_timeline_init(struct drm_i915_private *i915,
struct i915_gem_timeline *tl,
const char *name);
+int i915_gem_timeline_init__global(struct drm_i915_private *i915);
void i915_gem_timeline_fini(struct i915_gem_timeline *tl);
#endif
--
2.10.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related
* [CI 01/10] drm/i915: Give each sw_fence its own lockclass
From: Chris Wilson @ 2016-11-14 20:40 UTC (permalink / raw)
To: intel-gfx
Localise the static struct lock_class_key to the caller of
i915_sw_fence_init() so that we create a lock_class instance for each
unique sw_fence rather than all sw_fences sharing the same
lock_class. This eliminate some lockdep false positive when using fences
from within fence callbacks.
For the relatively small number of fences currently in use [2], this adds
160 bytes of unused text/code when lockdep is disabled. This seems
quite high, but fully reducing it via ifdeffery is also quite ugly.
Removing the #fence strings saves 72 bytes with just a single #ifdef.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
drivers/gpu/drm/i915/i915_sw_fence.c | 7 +++++--
drivers/gpu/drm/i915/i915_sw_fence.h | 17 ++++++++++++++++-
2 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c
index 95f2f12e0917..147420ccf49c 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence.c
+++ b/drivers/gpu/drm/i915/i915_sw_fence.c
@@ -116,11 +116,14 @@ static void i915_sw_fence_await(struct i915_sw_fence *fence)
WARN_ON(atomic_inc_return(&fence->pending) <= 1);
}
-void i915_sw_fence_init(struct i915_sw_fence *fence, i915_sw_fence_notify_t fn)
+void __i915_sw_fence_init(struct i915_sw_fence *fence,
+ i915_sw_fence_notify_t fn,
+ const char *name,
+ struct lock_class_key *key)
{
BUG_ON((unsigned long)fn & ~I915_SW_FENCE_MASK);
- init_waitqueue_head(&fence->wait);
+ __init_waitqueue_head(&fence->wait, name, key);
kref_init(&fence->kref);
atomic_set(&fence->pending, 1);
fence->flags = (unsigned long)fn;
diff --git a/drivers/gpu/drm/i915/i915_sw_fence.h b/drivers/gpu/drm/i915/i915_sw_fence.h
index 707dfc4f0da5..7508d23f823b 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence.h
+++ b/drivers/gpu/drm/i915/i915_sw_fence.h
@@ -40,7 +40,22 @@ typedef int (*i915_sw_fence_notify_t)(struct i915_sw_fence *,
enum i915_sw_fence_notify state);
#define __i915_sw_fence_call __aligned(4)
-void i915_sw_fence_init(struct i915_sw_fence *fence, i915_sw_fence_notify_t fn);
+void __i915_sw_fence_init(struct i915_sw_fence *fence,
+ i915_sw_fence_notify_t fn,
+ const char *name,
+ struct lock_class_key *key);
+#ifdef CONFIG_LOCKDEP
+#define i915_sw_fence_init(fence, fn) \
+do { \
+ static struct lock_class_key __key; \
+ \
+ __i915_sw_fence_init((fence), (fn), #fence, &__key); \
+} while (0)
+#else
+#define i915_sw_fence_init(fence, fn) \
+ __i915_sw_fence_init((fence), (fn), NULL, NULL)
+#endif
+
void i915_sw_fence_commit(struct i915_sw_fence *fence);
int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence,
--
2.10.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related
* [Buildroot] [git commit] toolchain: Bump ARC tools to arc-2016.09-rc1
From: Thomas Petazzoni @ 2016-11-14 20:40 UTC (permalink / raw)
To: buildroot
commit: https://git.buildroot.net/buildroot/commit/?id=6e0d4bac19f8144b9dc56851ae98a476ed9e5363
branch: https://git.buildroot.net/buildroot/commit/?id=refs/heads/master
As described at:
4520524ba055706236db9f00dd79f1b2e2e87fde
this commit continues a series of updates of ARC tools.
This time we're updating tools to arc-2016.09-rc1.
This update contains a lot of important fixes, e.g. it fixes:
http://autobuild.buildroot.net/results/4c7/4c77f33c842b37bf28cb931edf1b290e1bf4d93c//
http://autobuild.buildroot.net/results/902/902729a0b98675ad803939e3ecdcf230065a6012//
and other failures.
Other important change is that we also update gdb. Now we are
using gdb 7.12.
This version of gdb requires C++ toolchain support so we add
corresponding dependency to gdb Config.in file.
Signed-off-by: Vlad Zakharov <vzakhar@synopsys.com>
[Thomas:
- fix dependency on C++ of gdb, it must use BR2_INSTALL_LIBSTDCPP
- add comment about the C++ dependency of gdb on ARC.]
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
package/binutils/Config.in.host | 2 +-
.../{arc-2016.09-eng015 => arc-2016.09-rc1}/0300-ld-makefile.patch | 0
.../0301-check-ldrunpath-length.patch | 0
.../0500-add-sysroot-fix-from-bug-3049.patch | 0
.../0600-poison-system-directories.patch | 0
package/binutils/binutils.hash | 2 +-
package/binutils/binutils.mk | 2 +-
package/gcc/Config.in.host | 2 +-
.../301-missing-execinfo_h.patch | 0
.../{arc-2016.09-eng015 => arc-2016.09-rc1}/860-cilk-wchar.patch | 0
.../940-uclinux-enable-threads.patch | 0
package/gcc/gcc.hash | 2 +-
package/gdb/Config.in | 6 ++++++
package/gdb/Config.in.host | 2 +-
package/gdb/gdb.hash | 2 +-
15 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/package/binutils/Config.in.host b/package/binutils/Config.in.host
index 3e0c357..af9339e 100644
--- a/package/binutils/Config.in.host
+++ b/package/binutils/Config.in.host
@@ -22,7 +22,7 @@ endchoice
config BR2_BINUTILS_VERSION
string
- default "arc-2016.09-eng015" if BR2_arc
+ default "arc-2016.09-rc1" if BR2_arc
default "2.25.1" if BR2_BINUTILS_VERSION_2_25_X
default "2.26.1" if BR2_BINUTILS_VERSION_2_26_X
default "2.27" if BR2_BINUTILS_VERSION_2_27_X
diff --git a/package/binutils/arc-2016.09-eng015/0300-ld-makefile.patch b/package/binutils/arc-2016.09-rc1/0300-ld-makefile.patch
similarity index 100%
rename from package/binutils/arc-2016.09-eng015/0300-ld-makefile.patch
rename to package/binutils/arc-2016.09-rc1/0300-ld-makefile.patch
diff --git a/package/binutils/arc-2016.09-eng015/0301-check-ldrunpath-length.patch b/package/binutils/arc-2016.09-rc1/0301-check-ldrunpath-length.patch
similarity index 100%
rename from package/binutils/arc-2016.09-eng015/0301-check-ldrunpath-length.patch
rename to package/binutils/arc-2016.09-rc1/0301-check-ldrunpath-length.patch
diff --git a/package/binutils/arc-2016.09-eng015/0500-add-sysroot-fix-from-bug-3049.patch b/package/binutils/arc-2016.09-rc1/0500-add-sysroot-fix-from-bug-3049.patch
similarity index 100%
rename from package/binutils/arc-2016.09-eng015/0500-add-sysroot-fix-from-bug-3049.patch
rename to package/binutils/arc-2016.09-rc1/0500-add-sysroot-fix-from-bug-3049.patch
diff --git a/package/binutils/arc-2016.09-eng015/0600-poison-system-directories.patch b/package/binutils/arc-2016.09-rc1/0600-poison-system-directories.patch
similarity index 100%
rename from package/binutils/arc-2016.09-eng015/0600-poison-system-directories.patch
rename to package/binutils/arc-2016.09-rc1/0600-poison-system-directories.patch
diff --git a/package/binutils/binutils.hash b/package/binutils/binutils.hash
index f41b39b..80ac9dd 100644
--- a/package/binutils/binutils.hash
+++ b/package/binutils/binutils.hash
@@ -5,4 +5,4 @@ sha512 9d9165609fd3b0f20d616f9891fc8e2b466eb13e2bfce40125e12427f8f201d20e2b8322
sha512 cf276f84935312361a2ca077e04d0b469d23a3aed979d8ba5d92ea590904ffb2c2e7ed12cc842822bfc402836be86f479660cef3791aa62f3753d8a1a6f564cb binutils-2.27.tar.bz2
# Locally calculated (fetched from Github)
-sha512 f8cc7529fbe3cb52b666b92e1353063a8a36ea07fa8c5aa8359252f4222feaed15253b6a137033c74dabc0ae784daf8a7978e69ebdb8bf8cd6b8bb61c84bf181 binutils-arc-2016.09-eng015.tar.gz
+sha512 d0befdeb0a7b76efd1ad655fc062cde2aa67be7b26210c913ab2709e069d815c4ff2863ce7add1f6434da5a2f4faf1ce5a5bc3d0e64f3e04548a7479f24edcbc binutils-arc-2016.09-rc1.tar.gz
diff --git a/package/binutils/binutils.mk b/package/binutils/binutils.mk
index ca481d2..61486a2 100644
--- a/package/binutils/binutils.mk
+++ b/package/binutils/binutils.mk
@@ -9,7 +9,7 @@
BINUTILS_VERSION = $(call qstrip,$(BR2_BINUTILS_VERSION))
ifeq ($(BINUTILS_VERSION),)
ifeq ($(BR2_arc),y)
-BINUTILS_VERSION = arc-2016.09-eng015
+BINUTILS_VERSION = arc-2016.09-rc1
else
BINUTILS_VERSION = 2.25.1
endif
diff --git a/package/gcc/Config.in.host b/package/gcc/Config.in.host
index 0a63e6a..d10798b 100644
--- a/package/gcc/Config.in.host
+++ b/package/gcc/Config.in.host
@@ -98,7 +98,7 @@ config BR2_GCC_VERSION
default "4.9.4" if BR2_GCC_VERSION_4_9_X
default "5.4.0" if BR2_GCC_VERSION_5_X
default "6.2.0" if BR2_GCC_VERSION_6_X
- default "arc-2016.09-eng015" if BR2_GCC_VERSION_ARC
+ default "arc-2016.09-rc1" if BR2_GCC_VERSION_ARC
config BR2_EXTRA_GCC_CONFIG_OPTIONS
string "Additional gcc options"
diff --git a/package/gcc/arc-2016.09-eng015/301-missing-execinfo_h.patch b/package/gcc/arc-2016.09-rc1/301-missing-execinfo_h.patch
similarity index 100%
rename from package/gcc/arc-2016.09-eng015/301-missing-execinfo_h.patch
rename to package/gcc/arc-2016.09-rc1/301-missing-execinfo_h.patch
diff --git a/package/gcc/arc-2016.09-eng015/860-cilk-wchar.patch b/package/gcc/arc-2016.09-rc1/860-cilk-wchar.patch
similarity index 100%
rename from package/gcc/arc-2016.09-eng015/860-cilk-wchar.patch
rename to package/gcc/arc-2016.09-rc1/860-cilk-wchar.patch
diff --git a/package/gcc/arc-2016.09-eng015/940-uclinux-enable-threads.patch b/package/gcc/arc-2016.09-rc1/940-uclinux-enable-threads.patch
similarity index 100%
rename from package/gcc/arc-2016.09-eng015/940-uclinux-enable-threads.patch
rename to package/gcc/arc-2016.09-rc1/940-uclinux-enable-threads.patch
diff --git a/package/gcc/gcc.hash b/package/gcc/gcc.hash
index ce738ef..e5d96f4 100644
--- a/package/gcc/gcc.hash
+++ b/package/gcc/gcc.hash
@@ -12,4 +12,4 @@ sha512 2941cc950c8f2409a314df497631f9b0266211aa74746c1839c46e04f1c7c299afe2528d
sha512 1e8b826a3d44b9d5899309894e20c03abeb352bf3d273b8ad63af814c0ee2911f1a83ce1cd4cdd2d1cb0b3e3c34e9b7ae1b2ab83dfc649ee817ab05247c76198 gcc-6.2.0.tar.bz2
# Locally calculated (fetched from Github)
-sha512 9f365452f746ae91875d935c2ec5ed16cd11a2973f69bd23193fec9fc6b557e0dd66bb169e7efb7ec63fd78af36139005abcf5a5a1d89d6f49788b2ed7b334fb gcc-arc-2016.09-eng015.tar.gz
+sha512 7029d7ae1316b9385880f32283aa6c4979b1257500bb21e3fb234475ecb20082f46b114d8b7022c75a8dcf0c0c7b6b02e9384b49dd3189adc3d454502b8b0c26 gcc-arc-2016.09-rc1.tar.gz
diff --git a/package/gdb/Config.in b/package/gdb/Config.in
index 809e02d..0c6966a 100644
--- a/package/gdb/Config.in
+++ b/package/gdb/Config.in
@@ -2,6 +2,10 @@ comment "gdb/gdbserver needs a toolchain w/ threads, threads debug"
depends on !BR2_nios2 && !BR2_bfin
depends on !BR2_TOOLCHAIN_HAS_THREADS || !BR2_TOOLCHAIN_HAS_THREADS_DEBUG
+comment "gdb/gdbserver needs a toolchain w/ C++"
+ depends on BR2_arc
+ depends on !BR2_INSTALL_LIBSTDCPP
+
config BR2_PACKAGE_GDB
bool "gdb"
# When the external toolchain gdbserver is copied to the
@@ -11,6 +15,8 @@ config BR2_PACKAGE_GDB
(!BR2_PACKAGE_GDB_DEBUGGER && !BR2_TOOLCHAIN_EXTERNAL_GDB_SERVER_COPY)
depends on BR2_TOOLCHAIN_HAS_THREADS && BR2_TOOLCHAIN_HAS_THREADS_DEBUG
depends on !BR2_nios2 && !BR2_bfin
+ # Since ARC gdb moved to 7.12 toolchain requires C++ support to build gdb.
+ depends on !BR2_arc || BR2_INSTALL_LIBSTDCPP
help
GDB, the GNU Project debugger, allows you to see what is
going on `inside' another program while it executes -- or
diff --git a/package/gdb/Config.in.host b/package/gdb/Config.in.host
index a36dc0f..b6eb41f 100644
--- a/package/gdb/Config.in.host
+++ b/package/gdb/Config.in.host
@@ -56,7 +56,7 @@ endif
config BR2_GDB_VERSION
string
depends on BR2_PACKAGE_GDB || BR2_PACKAGE_HOST_GDB
- default "arc-2016.03-gdb" if BR2_arc
+ default "arc-2016.09-rc1-gdb" if BR2_arc
default "6be65fb56ea6694a9260733a536a023a1e2d4d57" if BR2_microblaze
default "7.9.1" if BR2_GDB_VERSION_7_9
default "7.10.1" if BR2_GDB_VERSION_7_10 || !BR2_PACKAGE_HOST_GDB
diff --git a/package/gdb/gdb.hash b/package/gdb/gdb.hash
index 611a75c..8c0d51b 100644
--- a/package/gdb/gdb.hash
+++ b/package/gdb/gdb.hash
@@ -5,4 +5,4 @@ sha512 f80ec6c8a0f0b54c8b945666e875809174402b7e121efb378ebac931a91f9a1cc0048568
# Locally calculated (fetched from Github)
sha512 0a467091d4b01fbecabb4b8da1cb743025c70e7f4874a0b5c8fa2ec623569a39bde6762b91806de0be6e63711aeb6909715cfbe43860de73d8aec6159a9f10a7 gdb-6be65fb56ea6694a9260733a536a023a1e2d4d57.tar.gz
-sha512 1abef1357896c2b57cfa7f7414eedc49d0de26b54321c680c2d027b1a27ec453d421e7f89a5281336047542379fd4820685802059efbd32b87c5ccffbaf2bd16 gdb-arc-2016.03-gdb.tar.gz
+sha512 e6019ac0d6b1354943d3c06c84f353ba49fef105b07c1a04ad90cc5b65f91e38fe6c671e0c34a9541ee282d0f42cf24579c011a0469d19faaa4d00d64a17afe2 gdb-arc-2016.09-rc1-gdb.tar.gz
^ permalink raw reply related
* [U-Boot] [PATCH v3 4/4] colibri_pxa270: transition to driver model for serial
From: Marcel Ziswiler @ 2016-11-14 20:40 UTC (permalink / raw)
To: u-boot
In-Reply-To: <1479156028-30553-1-git-send-email-marcel.ziswiler@toradex.com>
Add serial platform data to board file.
Enable driver model for PXA serial driver.
Signed-off-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
---
Changes in v3: None
Changes in v2:
- Drop baudrate checks.
- Use panic instead of just hang() to more gracefully handle
failure case.
- Drop superfluous parenthesis around plat->base.
- Capitalise header file gating macro.
- Replace tab with space after #define.
board/toradex/colibri_pxa270/colibri_pxa270.c | 18 ++++++++++++++++--
configs/colibri_pxa270_defconfig | 2 ++
include/configs/colibri_pxa270.h | 2 --
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/board/toradex/colibri_pxa270/colibri_pxa270.c b/board/toradex/colibri_pxa270/colibri_pxa270.c
index de8cb28..932b900 100644
--- a/board/toradex/colibri_pxa270/colibri_pxa270.c
+++ b/board/toradex/colibri_pxa270/colibri_pxa270.c
@@ -9,10 +9,13 @@
#include <common.h>
#include <asm/arch/hardware.h>
-#include <asm/arch/regs-mmc.h>
#include <asm/arch/pxa.h>
-#include <netdev.h>
+#include <asm/arch/regs-mmc.h>
+#include <asm/arch/regs-uart.h>
#include <asm/io.h>
+#include <dm/platdata.h>
+#include <dm/platform_data/serial_pxa.h>
+#include <netdev.h>
#include <serial.h>
#include <usb.h>
@@ -113,3 +116,14 @@ int board_mmc_init(bd_t *bis)
return 0;
}
#endif
+
+static const struct pxa_serial_platdata serial_platdata = {
+ .base = (struct pxa_uart_regs *)FFUART_BASE,
+ .port = FFUART_INDEX,
+ .baudrate = CONFIG_BAUDRATE,
+};
+
+U_BOOT_DEVICE(pxa_serials) = {
+ .name = "serial_pxa",
+ .platdata = &serial_platdata,
+};
diff --git a/configs/colibri_pxa270_defconfig b/configs/colibri_pxa270_defconfig
index 0b5c20d..e0a36f1 100644
--- a/configs/colibri_pxa270_defconfig
+++ b/configs/colibri_pxa270_defconfig
@@ -16,6 +16,8 @@ CONFIG_CMD_DHCP=y
CONFIG_CMD_PING=y
CONFIG_CMD_EXT2=y
CONFIG_CMD_FAT=y
+CONFIG_DM=y
+CONFIG_DM_SERIAL=y
CONFIG_PXA_SERIAL=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
diff --git a/include/configs/colibri_pxa270.h b/include/configs/colibri_pxa270.h
index 9f7c4a5..51f7877 100644
--- a/include/configs/colibri_pxa270.h
+++ b/include/configs/colibri_pxa270.h
@@ -47,8 +47,6 @@
/*
* Serial Console Configuration
*/
-#define CONFIG_FFUART 1
-#define CONFIG_CONS_INDEX 3
#define CONFIG_BAUDRATE 115200
/*
--
2.5.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.