Skip to content

Commit

Permalink
drm/nouveau: make client's notify array dynamic
Browse files Browse the repository at this point in the history
The number of notify objects per channel varies by several factors, and
now with the error notifier it depends also linearly on the number of
channels. Instead of the fixed 32, reallocate the notify object array to
twice the previous space when adding a new element if it's full. The
first allocation size is 16.

Note that this doesn't grow boundless even though the array never
shrinks and is only completely deleted at dtor(). Dead notify objects
are replaced with NULL and those slots are reused when new ones are
allocated, as before.

Change-Id: I970e7e0f334e3ba8626ab07b8e6d3569339f39bc
Signed-off-by: Konsta Holtta <kholtta@nvidia.com>
Reviewed-on: https://chromium-review.googlesource.com/304520
Reviewed-by: Vince Hsu <vince.h@nvidia.com>
Reviewed-by: Andrew Bresticker <abrestic@chromium.org>
  • Loading branch information
Konsta Holtta authored and chrome-bot committed Oct 9, 2015
1 parent b43919a commit 1ca2ab9
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 9 deletions.
3 changes: 2 additions & 1 deletion drivers/gpu/drm/nouveau/include/nvkm/core/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ struct nvkm_client {
void *data;

int (*ntfy)(const void *, u32, const void *, u32);
struct nvkm_client_notify *notify[32];
struct nvkm_client_notify **notify;
int notify_size;
};

static inline struct nvkm_client *
Expand Down
33 changes: 25 additions & 8 deletions drivers/gpu/drm/nouveau/nvkm/core/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ nvkm_client_notify(struct nvkm_notify *n)
int
nvkm_client_notify_put(struct nvkm_client *client, int index)
{
if (index < ARRAY_SIZE(client->notify)) {
if (index < client->notify_size) {
if (client->notify[index]) {
nvkm_notify_put(&client->notify[index]->n);
return 0;
Expand All @@ -64,7 +64,7 @@ nvkm_client_notify_put(struct nvkm_client *client, int index)
int
nvkm_client_notify_get(struct nvkm_client *client, int index)
{
if (index < ARRAY_SIZE(client->notify)) {
if (index < client->notify_size) {
if (client->notify[index]) {
nvkm_notify_get(&client->notify[index]->n);
return 0;
Expand All @@ -76,7 +76,7 @@ nvkm_client_notify_get(struct nvkm_client *client, int index)
int
nvkm_client_notify_del(struct nvkm_client *client, int index)
{
if (index < ARRAY_SIZE(client->notify)) {
if (index < client->notify_size) {
if (client->notify[index]) {
nvkm_notify_fini(&client->notify[index]->n);
kfree(client->notify[index]);
Expand All @@ -99,13 +99,25 @@ nvkm_client_notify_new(struct nvkm_object *object,
u8 index, reply;
int ret;

for (index = 0; index < ARRAY_SIZE(client->notify); index++) {
for (index = 0; index < client->notify_size; index++) {
if (!client->notify[index])
break;
}

if (index == ARRAY_SIZE(client->notify))
return -ENOSPC;
if (index == client->notify_size) {
int old_size = client->notify_size;
int new_size = old_size ? 2 * old_size : 16;
struct nvkm_client_notify **new_notify = kcalloc(new_size,
sizeof(*new_notify), GFP_KERNEL);

if (!new_notify)
return -ENOMEM;
memcpy(new_notify, client->notify,
old_size * sizeof(*new_notify));
kfree(client->notify);
client->notify = new_notify;
client->notify_size = new_size;
}

notify = kzalloc(sizeof(*notify), GFP_KERNEL);
if (!notify)
Expand Down Expand Up @@ -181,8 +193,11 @@ nvkm_client_dtor(struct nvkm_object *object)
{
struct nvkm_client *client = (void *)object;
int i;
for (i = 0; i < ARRAY_SIZE(client->notify); i++)
for (i = 0; i < client->notify_size; i++)
nvkm_client_notify_del(client, i);
kfree(client->notify);
client->notify = NULL;
client->notify_size = 0;
nvkm_object_ref(NULL, &client->device);
nvkm_handle_destroy(client->root);
nvkm_namedb_destroy(&client->namedb);
Expand Down Expand Up @@ -227,6 +242,8 @@ nvkm_client_create_(const char *name, u64 devname, const char *cfg,
nvkm_object_ref(device, &client->device);
snprintf(client->name, sizeof(client->name), "%s", name);
client->debug = nvkm_dbgopt(dbg, "CLIENT");
client->notify = NULL;
client->notify_size = 0;
return 0;
}

Expand All @@ -247,7 +264,7 @@ nvkm_client_fini(struct nvkm_client *client, bool suspend)
int ret, i;
nv_debug(client, "%s running\n", name[suspend]);
nv_debug(client, "%s notify\n", name[suspend]);
for (i = 0; i < ARRAY_SIZE(client->notify); i++)
for (i = 0; i < client->notify_size; i++)
nvkm_client_notify_put(client, i);
nv_debug(client, "%s object\n", name[suspend]);
ret = nvkm_handle_fini(client->root, suspend);
Expand Down

0 comments on commit 1ca2ab9

Please sign in to comment.