diff options
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/device.c | 9 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 4 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/resource.c | 26 |
3 files changed, 36 insertions, 3 deletions
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index feeb8ee6f4a2..44161ca4d2a8 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c | |||
| @@ -875,6 +875,11 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev) | |||
| 875 | 875 | ||
| 876 | rdev->status_page->db_off = 0; | 876 | rdev->status_page->db_off = 0; |
| 877 | 877 | ||
| 878 | init_completion(&rdev->rqt_compl); | ||
| 879 | init_completion(&rdev->pbl_compl); | ||
| 880 | kref_init(&rdev->rqt_kref); | ||
| 881 | kref_init(&rdev->pbl_kref); | ||
| 882 | |||
| 878 | return 0; | 883 | return 0; |
| 879 | err_free_status_page_and_wr_log: | 884 | err_free_status_page_and_wr_log: |
| 880 | if (c4iw_wr_log && rdev->wr_log) | 885 | if (c4iw_wr_log && rdev->wr_log) |
| @@ -893,13 +898,15 @@ destroy_resource: | |||
| 893 | 898 | ||
| 894 | static void c4iw_rdev_close(struct c4iw_rdev *rdev) | 899 | static void c4iw_rdev_close(struct c4iw_rdev *rdev) |
| 895 | { | 900 | { |
| 896 | destroy_workqueue(rdev->free_workq); | ||
| 897 | kfree(rdev->wr_log); | 901 | kfree(rdev->wr_log); |
| 898 | c4iw_release_dev_ucontext(rdev, &rdev->uctx); | 902 | c4iw_release_dev_ucontext(rdev, &rdev->uctx); |
| 899 | free_page((unsigned long)rdev->status_page); | 903 | free_page((unsigned long)rdev->status_page); |
| 900 | c4iw_pblpool_destroy(rdev); | 904 | c4iw_pblpool_destroy(rdev); |
| 901 | c4iw_rqtpool_destroy(rdev); | 905 | c4iw_rqtpool_destroy(rdev); |
| 906 | wait_for_completion(&rdev->pbl_compl); | ||
| 907 | wait_for_completion(&rdev->rqt_compl); | ||
| 902 | c4iw_ocqp_pool_destroy(rdev); | 908 | c4iw_ocqp_pool_destroy(rdev); |
| 909 | destroy_workqueue(rdev->free_workq); | ||
| 903 | c4iw_destroy_resource(&rdev->resource); | 910 | c4iw_destroy_resource(&rdev->resource); |
| 904 | } | 911 | } |
| 905 | 912 | ||
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index cc929002c05e..a60def23e9ef 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | |||
| @@ -185,6 +185,10 @@ struct c4iw_rdev { | |||
| 185 | struct wr_log_entry *wr_log; | 185 | struct wr_log_entry *wr_log; |
| 186 | int wr_log_size; | 186 | int wr_log_size; |
| 187 | struct workqueue_struct *free_workq; | 187 | struct workqueue_struct *free_workq; |
| 188 | struct completion rqt_compl; | ||
| 189 | struct completion pbl_compl; | ||
| 190 | struct kref rqt_kref; | ||
| 191 | struct kref pbl_kref; | ||
| 188 | }; | 192 | }; |
| 189 | 193 | ||
| 190 | static inline int c4iw_fatal_error(struct c4iw_rdev *rdev) | 194 | static inline int c4iw_fatal_error(struct c4iw_rdev *rdev) |
diff --git a/drivers/infiniband/hw/cxgb4/resource.c b/drivers/infiniband/hw/cxgb4/resource.c index 3cf25997ed2b..0ef25ae05e6f 100644 --- a/drivers/infiniband/hw/cxgb4/resource.c +++ b/drivers/infiniband/hw/cxgb4/resource.c | |||
| @@ -260,12 +260,22 @@ u32 c4iw_pblpool_alloc(struct c4iw_rdev *rdev, int size) | |||
| 260 | rdev->stats.pbl.cur += roundup(size, 1 << MIN_PBL_SHIFT); | 260 | rdev->stats.pbl.cur += roundup(size, 1 << MIN_PBL_SHIFT); |
| 261 | if (rdev->stats.pbl.cur > rdev->stats.pbl.max) | 261 | if (rdev->stats.pbl.cur > rdev->stats.pbl.max) |
| 262 | rdev->stats.pbl.max = rdev->stats.pbl.cur; | 262 | rdev->stats.pbl.max = rdev->stats.pbl.cur; |
| 263 | kref_get(&rdev->pbl_kref); | ||
| 263 | } else | 264 | } else |
| 264 | rdev->stats.pbl.fail++; | 265 | rdev->stats.pbl.fail++; |
| 265 | mutex_unlock(&rdev->stats.lock); | 266 | mutex_unlock(&rdev->stats.lock); |
| 266 | return (u32)addr; | 267 | return (u32)addr; |
| 267 | } | 268 | } |
| 268 | 269 | ||
| 270 | static void destroy_pblpool(struct kref *kref) | ||
| 271 | { | ||
| 272 | struct c4iw_rdev *rdev; | ||
| 273 | |||
| 274 | rdev = container_of(kref, struct c4iw_rdev, pbl_kref); | ||
| 275 | gen_pool_destroy(rdev->pbl_pool); | ||
| 276 | complete(&rdev->pbl_compl); | ||
| 277 | } | ||
| 278 | |||
| 269 | void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size) | 279 | void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size) |
| 270 | { | 280 | { |
| 271 | pr_debug("addr 0x%x size %d\n", addr, size); | 281 | pr_debug("addr 0x%x size %d\n", addr, size); |
| @@ -273,6 +283,7 @@ void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size) | |||
| 273 | rdev->stats.pbl.cur -= roundup(size, 1 << MIN_PBL_SHIFT); | 283 | rdev->stats.pbl.cur -= roundup(size, 1 << MIN_PBL_SHIFT); |
| 274 | mutex_unlock(&rdev->stats.lock); | 284 | mutex_unlock(&rdev->stats.lock); |
| 275 | gen_pool_free(rdev->pbl_pool, (unsigned long)addr, size); | 285 | gen_pool_free(rdev->pbl_pool, (unsigned long)addr, size); |
| 286 | kref_put(&rdev->pbl_kref, destroy_pblpool); | ||
| 276 | } | 287 | } |
| 277 | 288 | ||
| 278 | int c4iw_pblpool_create(struct c4iw_rdev *rdev) | 289 | int c4iw_pblpool_create(struct c4iw_rdev *rdev) |
| @@ -310,7 +321,7 @@ int c4iw_pblpool_create(struct c4iw_rdev *rdev) | |||
| 310 | 321 | ||
| 311 | void c4iw_pblpool_destroy(struct c4iw_rdev *rdev) | 322 | void c4iw_pblpool_destroy(struct c4iw_rdev *rdev) |
| 312 | { | 323 | { |
| 313 | gen_pool_destroy(rdev->pbl_pool); | 324 | kref_put(&rdev->pbl_kref, destroy_pblpool); |
| 314 | } | 325 | } |
| 315 | 326 | ||
| 316 | /* | 327 | /* |
| @@ -331,12 +342,22 @@ u32 c4iw_rqtpool_alloc(struct c4iw_rdev *rdev, int size) | |||
| 331 | rdev->stats.rqt.cur += roundup(size << 6, 1 << MIN_RQT_SHIFT); | 342 | rdev->stats.rqt.cur += roundup(size << 6, 1 << MIN_RQT_SHIFT); |
| 332 | if (rdev->stats.rqt.cur > rdev->stats.rqt.max) | 343 | if (rdev->stats.rqt.cur > rdev->stats.rqt.max) |
| 333 | rdev->stats.rqt.max = rdev->stats.rqt.cur; | 344 | rdev->stats.rqt.max = rdev->stats.rqt.cur; |
| 345 | kref_get(&rdev->rqt_kref); | ||
| 334 | } else | 346 | } else |
| 335 | rdev->stats.rqt.fail++; | 347 | rdev->stats.rqt.fail++; |
| 336 | mutex_unlock(&rdev->stats.lock); | 348 | mutex_unlock(&rdev->stats.lock); |
| 337 | return (u32)addr; | 349 | return (u32)addr; |
| 338 | } | 350 | } |
| 339 | 351 | ||
| 352 | static void destroy_rqtpool(struct kref *kref) | ||
| 353 | { | ||
| 354 | struct c4iw_rdev *rdev; | ||
| 355 | |||
| 356 | rdev = container_of(kref, struct c4iw_rdev, rqt_kref); | ||
| 357 | gen_pool_destroy(rdev->rqt_pool); | ||
| 358 | complete(&rdev->rqt_compl); | ||
| 359 | } | ||
| 360 | |||
| 340 | void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size) | 361 | void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size) |
| 341 | { | 362 | { |
| 342 | pr_debug("addr 0x%x size %d\n", addr, size << 6); | 363 | pr_debug("addr 0x%x size %d\n", addr, size << 6); |
| @@ -344,6 +365,7 @@ void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size) | |||
| 344 | rdev->stats.rqt.cur -= roundup(size << 6, 1 << MIN_RQT_SHIFT); | 365 | rdev->stats.rqt.cur -= roundup(size << 6, 1 << MIN_RQT_SHIFT); |
| 345 | mutex_unlock(&rdev->stats.lock); | 366 | mutex_unlock(&rdev->stats.lock); |
| 346 | gen_pool_free(rdev->rqt_pool, (unsigned long)addr, size << 6); | 367 | gen_pool_free(rdev->rqt_pool, (unsigned long)addr, size << 6); |
| 368 | kref_put(&rdev->rqt_kref, destroy_rqtpool); | ||
| 347 | } | 369 | } |
| 348 | 370 | ||
| 349 | int c4iw_rqtpool_create(struct c4iw_rdev *rdev) | 371 | int c4iw_rqtpool_create(struct c4iw_rdev *rdev) |
| @@ -380,7 +402,7 @@ int c4iw_rqtpool_create(struct c4iw_rdev *rdev) | |||
| 380 | 402 | ||
| 381 | void c4iw_rqtpool_destroy(struct c4iw_rdev *rdev) | 403 | void c4iw_rqtpool_destroy(struct c4iw_rdev *rdev) |
| 382 | { | 404 | { |
| 383 | gen_pool_destroy(rdev->rqt_pool); | 405 | kref_put(&rdev->rqt_kref, destroy_rqtpool); |
| 384 | } | 406 | } |
| 385 | 407 | ||
| 386 | /* | 408 | /* |
